Advertisement
qdmitry

submap

Mar 1st, 2021
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.27 KB | None | 0 0
  1. template <typename Key, typename Value>
  2. class ConcurrentMap {
  3. public:
  4.     static_assert(std::is_integral_v<Key>, "ConcurrentMap supports only integer keys"s);
  5.  
  6.     struct Access {
  7.         Access(Value& valueToRef, std::mutex& mtx )
  8.                : ref_to_value(valueToRef), mutex_(mtx) {
  9.             mutex_.lock();
  10.         }
  11.  
  12.         ~Access() {
  13.             mutex_.unlock();
  14.         }
  15.  
  16.         Value& ref_to_value;
  17.         std::mutex& mutex_;
  18.     };
  19.  
  20.     explicit ConcurrentMap(size_t bucket_count)
  21.         : maps_(bucket_count),
  22.           bucketCount_(bucket_count),
  23.           mutexes_(bucket_count) {}
  24.  
  25.     Access operator[](const Key& key)
  26.     {
  27.         auto mapId = static_cast<uint64_t>(key) % bucketCount_;
  28.         return Access(maps_[mapId][key], mutexes_[mapId]);
  29.     }
  30.  
  31.     std::map<Key, Value> BuildOrdinaryMap()
  32.     {
  33.         std::map<Key, Value> result;
  34.         for (std::size_t idx = 0; idx < maps_.size(); ++idx) {
  35.             std::lock_guard<std::mutex> guard(mutexes_[idx]);
  36.  
  37.             for (auto const & [k, v] : maps_[idx]) {
  38.                 result[k] = v;
  39.             }
  40.         }
  41.  
  42.         return result;
  43.     }
  44.  
  45. private:
  46.     std::vector<std::map<Key,Value>> maps_;
  47.     size_t bucketCount_;
  48.     std::vector<std::mutex> mutexes_;
  49. };
  50.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement