Algorithm: 简单的并发Hash-Map
2016-11-22 00:00
330 查看
#include <list> #include <mutex> #include <vector> #include <utility> #include <string> #include <iostream> #include <memory> #include <type_traits> #include <initializer_list> #include <unordered_map> //BOOST #include <boost/optional.hpp> #include <boost/thread/locks.hpp> #include <boost/thread/shared_mutex.hpp> template<typename Key, typename Value, typename Hash=std::hash<Key>> class HashContainer { private: //HashMap中的桶. template<typename KeyT, typename ValueT> class Bucket { public: using BucketValue = std::pair<KeyT, ValueT>; //桶中的Key-Val using BucketData = std::list<BucketValue>; //Key-Val被存放在 list 中. using ConstIterator = typename BucketData::const_iterator; using Iterator = typename BucketData::iterator; Bucket() = default; Bucket(const Bucket<KeyT, ValueT>&) = delete; Bucket<KeyT, ValueT>& operator=(const Bucket<KeyT, ValueT>&) = delete; //通过key查找对应的值. std::pair<bool, ValueT> findValue(const Key& key)const { boost::shared_lock<boost::shared_mutex> sharedL{ this->sharedM }; const Iterator itr = this->findFromKey(key); return ((itr == this->data.end()) ? std::pair<bool, ValueT>{false, ValueT{}} : std::pair<bool, ValueT>{true, itr->second}); } //添加key-value到hash-map中. void addValue(const KeyT& key, const ValueT& value) //针对: lvalue { std::unique_lock<boost::shared_mutex> uniqueL{ this->sharedM }; const Iterator itr = this->findFromKey(key); this->addValueToContainer(key, value, itr); //注意这里! } //添加key-value到hash-map中. void addValue(KeyT&& key, ValueT&& value) //针对: rvalue { std::unique_lock<boost::shared_mutex> uniqueL{ this->sharedM }; const Iterator itr = this->findFromKey(key); this->addValueToContainer(std::move(key), std::move(value), itr); //注意这里! } //通过key来移除hash-map中的:key-value. void removeValue(const KeyT& key) { std::unique_lock<boost::shared_mutex> uniqueL{ this->sharedM }; ConstIterator itr = this->findFromKey(key); if (itr = (this->data).cend()) { (this->data).erase(itr); } } private: const Iterator findFromKey(const KeyT& key) { const Iterator cbeg = (this->data).begin(); //const Iterator其实相当于:ValueT* const ptr 是一个顶层const. const Iterator cend = (this->data).end(); const Iterator itr = std::find_if(cbeg, cend, [&key](const BucketValue& value)->bool { return (value.first == key) ? true : false; }); return itr; } template<typename K, typename V> void addValueToContainer(K&& key, V&& value, const Iterator itr) //完美转发插入的值. { if (itr == (this->data).cend()) { (this->data).push_back(std::pair<KeyT, ValueT>{std::forward<K>(key), std::forward<V>(value)}); } else { itr->second = std::forward<V>(value); } } BucketData data; mutable boost::shared_mutex sharedM{}; //Notice that. }; public: using KeyType = Key; using ValueType = Value; using HashType = Hash; HashContainer(const std::size_t& size = 19)try //notice that. : bucketNumbers(size) { std::lock_guard<std::mutex> locGuard{ this->mutex }; this->initialContainer(); }catch (const std::out_of_range& error) { std::cout << error.what() << std::endl; } ~HashContainer() = default; //Notice that. HashContainer(const HashContainer<Key, Value>&) = delete; HashContainer<Key, Value>& operator=(const HashContainer<Key, Value>&) = delete; std::size_t bucketNumber()const noexcept { return (this->buckets).size(); } template<typename K, typename V> void insert(K&& key, V&& value) { std::size_t hashVal = this->hashValue(key, typename std::is_class<Hash>::type{}); //标签分配. Bucket<Key, Value>& bucket = this->getBucket(hashVal); bucket.addValue(std::forward<K>(key), std::forward<V>(value)); } void erase(const Key& key) { std::size_t hashVal = this->hashValue(key); Bucket<Key, Value>& bucket = this->getBucket(hashVal); bucket.removeValue(key); } private: std::size_t hashValue(const Key& key, std::true_type) const noexcept { std::size_t hashVal{}; hashVal = this->hasher(key) % (this->bucketNumber()); return hashVal; //相当于返回 std::move(hashVal); } std::size_t hashValue(const Key& key, std::false_type)const noexcept { std::size_t hashVal{}; hashVal = *(this->hasher)(key) % (this->bucketNumber()); return hashVal; //相当于返回 std::move(hashVal); } Bucket<Key, Value>& getBucket(const std::size_t& size)noexcept { return (*(this->buckets)[size]); } void initialContainer() { if (this->bucketNumbers == 0) { throw std::out_of_range("out of range!"); } else { for (unsigned int i = 0; i < (this->bucketNumbers); ++i) { buckets.push_back(std::unique_ptr<Bucket<Key, Value>>{new Bucket<Key, Value>{}}); } buckets.shrink_to_fit(); } } Hash hasher{}; std::mutex mutex{}; std::size_t bucketNumbers{ 19 }; //初始桶的个数为19个. std::vector<std::unique_ptr<Bucket<Key, Value>>> buckets{}; }; int main() { HashContainer<int, int> container{}; container.insert(1, 20); return 0; }
相关文章推荐
- C++ hash_map简单应用之解析配置文件
- C++ map和hash_map简单对比
- 关于map、hash_map 和 unordered_map 的简单性能测试
- Map并发变成的三种写法,执行时间简单比较
- 简单运用Hash_map
- hash_map与map效率实验对比(简单)
- UnicodeEncoding HashAlgorithm CryptoConfig BitConverter
- Javascript SHA-1:Secure Hash Algorithm
- 最简单的线程并发例子
- Hash_table 的简单使用说明
- vc++2005 和 g++中使用hash_map
- 一个hash_map使用错误
- Tips:Map中在网格页之间移动Functoids原来这么简单...
- 详细解说STL hash_map系列
- linux下的简单共享内存map实现
- 详细解说STL hash_map系列
- 简单并发控制
- vc的hash_map怎么啦
- 详细解说STL hash_map系列
- ACE_Hash_Map的使用示例