#include #include #include #include #include #include #include template > class threadsafe_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 { std::size_t const bucket_index=hasher(key)%buckets.size(); return *buckets[bucket_index]; } public: typedef Key key_type; typedef Value mapped_type; typedef Hash hash_type; threadsafe_lookup_table( unsigned num_buckets=19, Hash const& hasher_=Hash()): buckets(num_buckets),hasher(hasher_) { for(unsigned i=0;i