196
84 void
85 put(const std::string &key, const Value &val)
86 {
87
auto index = std::hash{}(key) % N;
88
89
/* get pool on which this simple_kv resides */
90
auto pop = pmem::obj::pool_by_vptr(this);
91
92
/* search for element with specified key - if found
93
* update its value in a transaction*/
94
for (const auto &e : buckets[index]) {
95
if (e.first == key) {
96
pmem::obj::transaction::run(
97
pop, [&] { values[e.second] = val; });
98
99
return;
100
}
101
}
102
103
/* if there is no element with specified key, insert
104
* new value to the end of values vector and put
105
* reference in proper bucket */
106
pmem::obj::transaction::run(pop, [&] {
107
values.emplace_back(val);
108
buckets[index].emplace_back(key, values.size() - 1);
109
});
110
}
111 };
• Lines 58-66: Define the layout of a hash map as a pmem::obj::array
of buckets, where each bucket is a pmem::obj::vector of key and
index pairs and pmem::obj::vector contains the values. The index
in a bucket entry always specifies a position of the actual value
stored in a separate vector. For snapshotting optimization, the value
is not saved next to a key in a bucket. When obtaining a non-const
reference to an element in pmem::obj::vector, the element is always
Chapter 11 Designing Data struCtures for persistent MeMory
84 void
85 put(const std::string &key, const Value &val)
86 {
87
auto index = std::hash
88
89
/* get pool on which this simple_kv resides */
90
auto pop = pmem::obj::pool_by_vptr(this);
91
92
/* search for element with specified key - if found
93
* update its value in a transaction*/
94
for (const auto &e : buckets[index]) {
95
if (e.first == key) {
96
pmem::obj::transaction::run(
97
pop, [&] { values[e.second] = val; });
98
99
return;
100
}
101
}
102
103
/* if there is no element with specified key, insert
104
* new value to the end of values vector and put
105
* reference in proper bucket */
106
pmem::obj::transaction::run(pop, [&] {
107
values.emplace_back(val);
108
buckets[index].emplace_back(key, values.size() - 1);
109
});
110
}
111 };
• Lines 58-66: Define the layout of a hash map as a pmem::obj::array
of buckets, where each bucket is a pmem::obj::vector of key and
index pairs and pmem::obj::vector contains the values. The index
in a bucket entry always specifies a position of the actual value
stored in a separate vector. For snapshotting optimization, the value
is not saved next to a key in a bucket. When obtaining a non-const
reference to an element in pmem::obj::vector, the element is always
Chapter 11 Designing Data struCtures for persistent MeMory
