Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <future>
- #include <mutex>
- #include <unordered_map>
- #include <vector>
- #include <utility>
- #include <algorithm>
- #include <random>
- #include <thread>
- #include <shared_mutex>
- using namespace std;
- template<typename K, typename V, typename Hash = std::hash<K>>
- class ConcurrentMap {
- struct Key {
- K data;
- size_t hash;
- explicit Key(K data) : data(std::move(data)), hash(Hash()(this->data)) {}
- bool operator==(const Key &other) const {
- return data == other.data;
- }
- };
- struct KeyHasher {
- auto operator()(const Key &value) const {
- return value.hash;
- }
- };
- using InnerMapType = std::unordered_map<Key, V, KeyHasher>;
- struct SharedMap {
- mutable std::shared_mutex mtx;
- InnerMapType map;
- };
- public:
- using MapType = std::unordered_map<K, V, Hash>;
- class WriteAccess {
- std::lock_guard<std::shared_mutex> guard;
- public:
- V &ref_to_value;
- WriteAccess(InnerMapType &map, Key &key, std::shared_mutex &mtx) : guard(mtx),
- ref_to_value(map[std::move(key)]) {};
- };
- class ReadAccess {
- std::shared_lock<std::shared_mutex> lock;
- public:
- const V &ref_to_value;
- ReadAccess(const InnerMapType &map, const Key &key, std::shared_mutex &mtx) : lock(mtx),
- ref_to_value(map.at(key)) {};
- };
- explicit ConcurrentMap(size_t bucket_count) : data(bucket_count) {}
- WriteAccess operator[](const K &key) {
- Key map_key(key);
- auto &[mtx, map] = data[map_key.hash % data.size()];
- return {map, map_key, mtx};
- }
- ReadAccess At(const K &key) const {
- const Key map_key(key);
- auto &[mtx, map] = data[map_key.hash % data.size()];
- return {map, map_key, mtx};
- }
- bool Has(const K &key) const {
- const Key map_key(key);
- auto &[mtx, map] = data[map_key.hash % data.size()];
- std::shared_lock locker(mtx);
- return map.find(map_key) != map.end();
- }
- MapType BuildOrdinaryMap() const {
- MapType to_ret;
- for (auto &[mtx, map] : data) {
- std::shared_lock locker(mtx);
- for (auto &[key, val] : map) {
- to_ret[key.data] = val;
- }
- }
- return to_ret;
- }
- private:
- std::vector<SharedMap> data;
- };
Add Comment
Please, Sign In to add comment