116
59
pmem::obj::transaction::run(pop, [&]() {
60
r->bad.some_int = 10;
61
r->good.pint = 10;
62
63
r->good.pint += 1;
64
});
65
66
return 0;
67
}
• Lines 39-42: Here, we declare a bad_example structure with two
variables – some_int and some_float. Storing this structure on
persistent memory and modifying it are dangerous because data is
not snapshotted automatically.
• Lines 44-47: We declare the good_example structure with two p<>
type variables – pint and pfloat. This structure can be safely stored
on persistent memory as every modification of pint or pfloat in a
transaction will perform a snapshot.
• Lines 55-57: Here, we open a persistent memory pool, created
already using the pmempool command, and obtain a pointer to the
root object stored within the root variable.
• Line 60: We modify the integer value from the bad_example structure.
This modification is not safe because we do not add this variable to
the transaction; hence it will not be correctly made persistent if there
is an unexpected application or system crash or power failure.
• Line 61: Here, we modify integer value wrapped by p<> template. This
is safe because operator=() will automatically snapshot the element.
• Line 63: Using arithmetic operators on p<> (if the underlying type
supports it) is also safe.
Allocating
As with std::shared_ptr, the pmem::obj::persistent_ptr comes with a set of allocating
and deallocating functions. This helps allocate memory and create objects, as well as
destroy and deallocate the memory. This is especially important in the case of persistent
Chapter 8 libpmemobj-Cpp: the adaptable language - C++ and persistent memory
59
pmem::obj::transaction::run(pop, [&]() {
60
r->bad.some_int = 10;
61
r->good.pint = 10;
62
63
r->good.pint += 1;
64
});
65
66
return 0;
67
}
• Lines 39-42: Here, we declare a bad_example structure with two
variables – some_int and some_float. Storing this structure on
persistent memory and modifying it are dangerous because data is
not snapshotted automatically.
• Lines 44-47: We declare the good_example structure with two p<>
type variables – pint and pfloat. This structure can be safely stored
on persistent memory as every modification of pint or pfloat in a
transaction will perform a snapshot.
• Lines 55-57: Here, we open a persistent memory pool, created
already using the pmempool command, and obtain a pointer to the
root object stored within the root variable.
• Line 60: We modify the integer value from the bad_example structure.
This modification is not safe because we do not add this variable to
the transaction; hence it will not be correctly made persistent if there
is an unexpected application or system crash or power failure.
• Line 61: Here, we modify integer value wrapped by p<> template. This
is safe because operator=() will automatically snapshot the element.
• Line 63: Using arithmetic operators on p<> (if the underlying type
supports it) is also safe.
Allocating
As with std::shared_ptr, the pmem::obj::persistent_ptr comes with a set of allocating
and deallocating functions. This helps allocate memory and create objects, as well as
destroy and deallocate the memory. This is especially important in the case of persistent
Chapter 8 libpmemobj-Cpp: the adaptable language - C++ and persistent memory
