1515
1616#include < iostream>
1717
18+ struct date {
19+ pmem::obj::p<uint64_t > year;
20+ pmem::obj::p<uint64_t > month;
21+ pmem::obj::p<uint64_t > day;
22+ };
23+
1824/* Pmem-resident data type. */
1925struct city_info {
2026 city_info (uint64_t population, uint64_t area_in_sqr_km,
21- std::string country) /* std::string is passed here since
22- pmem::obj::string cannot be used on
23- dram */
27+ std::string country,
28+ date upd_date = date{2021 , 1 , 1 }) /* std::string
29+ is passed here since pmem::obj::string
30+ cannot be used on dram */
2431 : population(population),
2532 area_in_sqr_km (area_in_sqr_km),
26- country(country)
33+ country(country),
34+ latest_update_date(upd_date)
2735 {
2836 }
2937
3038 pmem::obj::p<uint64_t > population;
3139 pmem::obj::p<uint64_t > area_in_sqr_km;
3240 pmem::obj::string country;
41+
42+ /* If some fields are often updated at the same time, it might
43+ * be better to put them inside a structure and wrap the whole structure
44+ * in pmem::obj::p<>. By doing this, number of snapshots can be reduced
45+ * (which means better performance).
46+ */
47+ pmem::obj::p<date> latest_update_date;
3348};
3449
3550using kv_type = pmem::obj::experimental::radix_tree<
@@ -54,23 +69,49 @@ insert_elements_kv(pmem::obj::pool<root> pop)
5469 * The transaction guarantees that either all elements will be inserted
5570 * or none of them (even in case of failure). */
5671 pmem::obj::transaction::run (pop, [&] {
72+ /* Ok, construct city_info directly on pmem */
5773 r->kv ->try_emplace (" Gdansk" , 470907 , 262 , " Poland" );
5874 r->kv ->try_emplace (" Warsaw" , 1793579 , 517 , " Poland" );
5975 r->kv ->try_emplace (" Krakow" , 779115 , 326 , " Poland" );
76+
77+ /* WRONG: cannot create city_info on stack (DRAM) since
78+ * pmem::obj::string can only be placed on pmem:
79+ *
80+ * city_info cs(470907, 262, "Poland");
81+ * r->kv->try_emplace("Ponzań", cs);
82+ *
83+ * r->kv->try_emplace("Poznań", city_info(470907, 262,
84+ * "Poland"));
85+ */
6086 });
6187
6288 kv_type::iterator it = r->kv ->find (" Gdansk" );
6389 assert (it != r->kv ->end ());
6490
6591 /* Update "Gdansk" information in a transaction.
6692 * The transaction guarantees that either both population and area will
67- * be updated or none of them (even in case of failure)
93+ * be updated or none of them (even in case of failure).
94+ *
95+ * This code will make two snaphots.
6896 */
6997 pmem::obj::transaction::run (pop, [&] {
7098 it->value ().population += 10000 ;
7199 it->value ().area_in_sqr_km += 10 ;
72100 });
73101
102+ /* Update "Gdańsk" latest_update_date field.
103+ *
104+ * This code will result in only one snaphot.
105+ */
106+ pmem::obj::transaction::run (pop, [&] {
107+ it->value ().latest_update_date .get_rw ().year = 2021 ;
108+ it->value ().latest_update_date .get_rw ().month = 3 ;
109+ it->value ().latest_update_date .get_rw ().day = 5 ;
110+
111+ /* OR */
112+ it->value ().latest_update_date = date{2021 , 3 , 5 };
113+ });
114+
74115 it = r->kv ->find (" Warsaw" );
75116 assert (it != r->kv ->end ());
76117
0 commit comments