C++ bindings for libpmemobj(part 0 - part 3)

参考链接:

http://pmem.io/2016/01/12/cpp-01.html

 

Part 0

有关之前 C 语言的 libpmemobj 库的目标是在不修改编译器的条件下实现持续性存储的所有功能,但是只能在低级软件和语言。

而 libpmemobj C++ 库是更高级的语言,减少错误并且具有更好的API。更多专注修改 structs 和 classes,而对函数共能只做简单修改。

 

Part 1

C 语言的 API 中存在的错误就是在事务操作中必须跟踪持久性内存变量的修改。

以vector example 为例子

pmem::obj::p 这个类不增加存储开销,但能够形成与C语言版本相同的 vector 结构体。在事务的操作中不需要再使用pmemobj_tx_add_range 函数。原因是:如果代码变得很复杂的时候在使用pmemobj_tx_add_range 函数时就会造成很多错误从而导致持久性问题。

 

Part 2

pmem::obj::persistent_ptr

使用 persistent_ptr 之后不再需要使用宏定义 layout 声明!!

这是原先的 layout 声明:

POBJ_LAYOUT_BEGIN(rect_calc);

        POBJ_LAYOUT_ROOT(rect_calc, struct my_root);

        POBJ_LAYOUT_TOID(rect_calc, struct rectangle);

POBJ_LAYOUT_END(rect_calc);

也不用再使用 D_RW 和 D_RO 宏可以直接使用 ”->” 

persistent_ptr rootp = pmemobj_root(pop, sizeof (root));

TX_BEGIN(pop) {
	persistent_ptr rect = pmemobj_tx_alloc(sizeof (rectangle), 0);
	rect->x = 5;
	rect->y = 10;

	rootp->rect = rect; /* assignments are automatically added to TX */
} TX_END
其中 persistent_ptr rect = pmemobj_tx_alloc(sizeof (rectangle), 0); 没有调用 rectangle 的构造函数。做如下理解:
shared_ptr rect((rectangle *)malloc(sizeof (rectangle)));

{

shared_ptr 用法参考如下链接:

https://www.cnblogs.com/diysoul/p/5930361.html

使用 C 语言 API中的 raw() 来释放 persistent_ptr 返回值的是 PMEMoid 的 const 型。

TX_BEGIN(pop) {
	pmemobj_tx_free(rootp->rect.raw());
	rootp->rect = nullptr;
} TX_END

persistent_ptr 类中也自带了一个 raw_ptr() 函数来返回一个指向 PMEMoid 的指针。

}

 

Part 3

链表队列

pmem_queue::push()

Step 1

首先需要创建一个新对象,包含数据和指向下一个的指针 next。

由于这些变量的初始化的内存内容并不知道,所以需要用户来赋值

 

Step 2

将现有的 queue 尾指针 next 指向新创键的对象

C++ bindings for libpmemobj(part 0 - part 3)_第1张图片

 

Step3

我们需要跟新tail的指向,将他指向新 push 进来的对象的 next 上。如果 push 进来的对象是第一个,那么 head 和 tail 都需要更新。

C++ bindings for libpmemobj(part 0 - part 3)_第2张图片

 

pmem_queue::pop()

Step1

跟新队列结构的head指向head->next。现在被移除的对象就不会链接任何的队列了。

Step2

被移除的对象会被释放。如果队列中没有任何对象了,那么将 tail 指向 NULL。

C++ 方法实现

对象结构体:

struct pmem_entry {
	persistent_ptr next;
	p value;
};

 根对象:

class pmem_queue {
private:
	persistent_ptr head;
	persistent_ptr tail;
};

使用 pmemobj_alloc()/pmemobj_free() 来代替 new/delete 会让 pmem_queue::push() 和 pmem_queue::pop() 函数具有非易失性。

例程实现如下

C++ bindings for libpmemobj(part 0 - part 3)_第3张图片

 

 

 

 

 

 

你可能感兴趣的:(PMDK)