// SPDX-License-Identifier: BSD-3-Clause /* Copyright 2019, Intel Corporation */ /* * simplekv.hpp -- implementation of simple kv which uses vector to hold * values, string as a key and array to hold buckets */ #include #include #include #include #include #include #include #include #include #include #include #include /** * Value - type of the value stored in hashmap * N - number of buckets in hashmap */ template class simple_kv { private: using key_type = pmem::obj::string; using bucket_type = pmem::obj::vector>; using bucket_array_type = pmem::obj::array; using value_vector = pmem::obj::vector; bucket_array_type buckets; value_vector values; public: simple_kv() = default; const Value & get(const std::string &key) const { auto index = std::hash{}(key) % N; for (const auto &e : buckets[index]) { if (e.first == key) return values[e.second]; } throw std::out_of_range("no entry in simplekv"); } void put(const std::string &key, const Value &val) { auto index = std::hash{}(key) % N; /* get pool on which this simple_kv resides */ auto pop = pmem::obj::pool_by_vptr(this); /* search for element with specified key - if found * transactionally update its value */ for (const auto &e : buckets[index]) { if (e.first == key) { pmem::obj::transaction::run( pop, [&] { values[e.second] = val; }); return; } } /* if there is no element with specified key, insert new value * to the end of values vector and put reference in proper * bucket transactionally */ pmem::obj::transaction::run(pop, [&] { values.emplace_back(val); buckets[index].emplace_back(key, values.size() - 1); }); } };