#include #include #include #include #include #include #include template > class lookup_table { private: class bucket_type { private: typedef std::pair bucket_value; typedef std::list bucket_data; typedef typename bucket_data::iterator bucket_iterator; bucket_data data; mutable boost::shared_mutex mutex; bucket_iterator find_entry_for(Key const& key) const { return std::find_if(data.begin(), data.end(), [&](bucket_value const& item) {return item.first == key;}); } public: Value value_for(Key const& key, Value const& default_value) const { boost::shared_lock lock(mutex); bucket_iterator const found_entry = find_entry_for(key); return (found_entry == data.end()) ? default_value : found_entry->second; } void add_or_update_mapping(Key const& key, Value const& value) { std::unique_lock lock(mutex); bucket_iterator const found_entry = find_entry_for(key); if (found_entry == data.end()) { data.push_back(bucket_value(key,value)); } else { found_entry->second = value; } } void remove_mapping(Key const& key) { std::unique_lock lock(mutex); bucket_iterator const found_entry = find_entry_for(key); if (found_entry != data.end()) { data.erase(found_entry); } } }; std::vector > buckets; Hash hasher; bucket_type& get_bucket(Key const& key) const { const std::size_t bucket_index = hasher(key) % buckets.size(); return *buckets[bucket_index]; } public: typedef Key key_type; typedef Value mapped_type; typedef Hash hash_type; lookup_table(unsigned num_buckets = 19, const Hash& hasher_ = Hash()) : buckets(num_buckets) , hasher(hasher_) { for (unsigned i = 0; i < num_buckets; ++i) { buckets[i].reset(new bucket_type); } } lookup_table(const lookup_table& other) = delete; lookup_table& operator=(const lookup_table& other) = delete; Value value_for(Key const& key, Value const& default_value = Value()) const { return get_bucket(key).value_for(key, default_value); } void add_or_update_mapping(const Key& key, const Value& value) { get_bucket(key).add_or_update_mapping(key, value); } void remove_mapping(const Key& key) { get_bucket(key).remove_mapping(key); } std::map get_map() const { std::vector > locks; for (unsigned i = 0; i < buckets.size(); ++i) { locks.push_back(boost::unique_lock( buckets[i].mutex)); } std::map res; for (unsigned i = 0; i < buckets.size(); ++i) { for (typename bucket_type::bucket_iterator it = buckets[i].data.begin(); it != buckets[i].data.end(); ++it) { res.insert(*it); } } return res; } }; int main() { lookup_table t; t.add_or_update_mapping(1,"hello"); std::cout << "value for 1 is " << t.value_for(1) << std::endl; return 0; }