template<typename Key, typename Value, typename Hash = std::hash<Key>> class ThreadsafeLookupTable { private: class BucketType { private: typedef std::pair<Key, Value> bucketValue; typedef std::list<bucketValue> bucketData; typedef typename bucketData::iterator bucketIterator; bucketData data; mutable boost::shared_mutex mutex; bucketIterator findEntryFor(Key const& key) const { return std::find_if(data.cbegin (), data.cend (), [&](bucketValue const& item) {return item.first == key;}); } public: Value valueFor(Key const& key, Value const& defaultValue) const { boost::shared_lock<boost::shared_mutex> lock(mutex); auto const foundEntry = findEntryFor (key); return (foundEntry == data.cend ()? defaultValue : foundEntry->second); } void addOrUpdate(Key const& key, Value const& value) { std::unique_lock<boost::shared_mutex> lock(mutex); auto const foundEntry = findEntryFor (key); if (foundEntry == data.cend ()){ data.push_back ({key, value}); } else{ foundEntry->second = value; } } void removeMapping(Key const& key) { std::unique_lock<boost::shared_mutex> lock(mutex); auto const foundEntry = findEntryFor (key); if (foundEntry != data.cend ()){ data.erase (foundEntry); } } }; std::vector<std::unique_ptr<BucketType>> buckets; Hash hasher; BucketType& getBucket(Key const& key) const { auto const bucketIdnex = hasher(key) % buckets.size (); return *buckets[bucketIdnex]; } public: ThreadsafeLookupTable(const ThreadsafeLookupTable&) = delete; ThreadsafeLookupTable& operator=(const ThreadsafeLookupTable&) = delete; typedef Key KeyType; typedef Value MappedValue; ThreadsafeLookupTable(size_t numBuckets = 19, Hash const& hasher_ = Hash()): buckets(std::vector<std::unique_ptr<BucketType>>(numBuckets)), hasher(hasher_) { for (size_t i = 0; i < numBuckets; ++i){ buckets[i].reset(std::make_unique<BucketType>()); } } Value valueFor(Key const& key, Value const& defaultValue) { getBucket (key).valueFor (key, defaultValue); } void addOrUpdateMapping(Key const& key, Value const& value) { getBucket (key).addOrUpdate (key, value); } void removeMapping(Key const& key) { getBucket (key).removeMapping (key); } };
时间: 2024-10-20 16:16:00