日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

cyber atomic hash map

發布時間:2024/7/23 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 cyber atomic hash map 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

整體結構

cyber atomic hash map是用一個數組存儲桶(bucket),桶是一個鏈表的形式存儲值,每一個結點是個entry,哈希沖突的解決方法是鏈地址法。

整體結構 --- entry

entry為bucket鏈表的結點單位,代碼:

struct Entry {Entry() {}explicit Entry(K key) : key(key) {value_ptr.store(new V(), std::memory_order_release);}Entry(K key, const V &value) : key(key) {value_ptr.store(new V(value), std::memory_order_release);}Entry(K key, V &&value) : key(key) {value_ptr.store(new V(std::forward<V>(value)), std::memory_order_release);}~Entry() { delete value_ptr.load(std::memory_order_acquire); }K key = 0;std::atomic<V *> value_ptr = {nullptr};std::atomic<Entry *> next = {nullptr}; };

存入每一個鍵值對的key,value,和同哈希值的next,需要注意的是value_ptr也就是指向value的指針,以及next指針都是原子的(atomic),也就是針對該指針的操作不需要考慮同步互斥問題。

整體結構 --- bucket

bucket串接的是一系列具有相同哈希值的鍵值對,且按照key升序串接,且具有一個頭節點head_:

class Bucket {public:...Entry *head_; };

bucket接口:

bool Has(K key)

bool Has(K key) {Entry *m_target = head_->next.load(std::memory_order_acquire);while (Entry *target = m_target) {if (target->key < key) {m_target = target->next.load(std::memory_order_acquire);continue;} else {return target->key == key;}}return false; }

由于每個buffer是個升序鏈表,所以可以如上尋找

bool Find(K key, Entry **prev_ptr, Entry **target_ptr)

bool Find(K key, Entry **prev_ptr, Entry **target_ptr) {Entry *prev = head_;Entry *m_target = head_->next.load(std::memory_order_acquire);while (Entry *target = m_target) {if (target->key == key) {*prev_ptr = prev;*target_ptr = target;return true;} else if (target->key > key) {*prev_ptr = prev;*target_ptr = target;return false;} else {prev = target;m_target = target->next.load(std::memory_order_acquire);}}*prev_ptr = prev;*target_ptr = nullptr;return false; }

void Insert(K key, const V &value)

void Insert(K key, const V &value) {Entry *prev = nullptr;Entry *target = nullptr;Entry *new_entry = nullptr;V *new_value = nullptr;while (true) {if (Find(key, &prev, &target)) {// key exists, update valueif (!new_value) {new_value = new V(value);}auto old_val_ptr = target->value_ptr.load(std::memory_order_acquire);if (target->value_ptr.compare_exchange_strong(old_val_ptr, new_value, std::memory_order_acq_rel,std::memory_order_relaxed)) {delete old_val_ptr;if (new_entry) {delete new_entry;new_entry = nullptr;}return;}continue;} else {if (!new_entry) {new_entry = new Entry(key, value);}new_entry->next.store(target, std::memory_order_release);if (prev->next.compare_exchange_strong(target, new_entry,std::memory_order_acq_rel,std::memory_order_relaxed)) {// Insert successif (new_value) {delete new_value;new_value = nullptr;}return;}// another entry has been inserted, retry}} }

void Insert(K key, V &&value)

void Insert(K key, V &&value) {Entry *prev = nullptr;Entry *target = nullptr;Entry *new_entry = nullptr;V *new_value = nullptr;while (true) {if (Find(key, &prev, &target)) {// key exists, update valueif (!new_value) {new_value = new V(std::forward<V>(value));}auto old_val_ptr = target->value_ptr.load(std::memory_order_acquire);if (target->value_ptr.compare_exchange_strong(old_val_ptr, new_value, std::memory_order_acq_rel,std::memory_order_relaxed)) {delete old_val_ptr;if (new_entry) {delete new_entry;new_entry = nullptr;}return;}continue;} else {if (!new_entry) {new_entry = new Entry(key, value);}new_entry->next.store(target, std::memory_order_release);if (prev->next.compare_exchange_strong(target, new_entry,std::memory_order_acq_rel,std::memory_order_relaxed)) {// Insert successif (new_value) {delete new_value;new_value = nullptr;}return;}// another entry has been inserted, retry}} }

void Insert(K key)

void Insert(K key) {Entry *prev = nullptr;Entry *target = nullptr;Entry *new_entry = nullptr;V *new_value = nullptr;while (true) {if (Find(key, &prev, &target)) {// key exists, update valueif (!new_value) {new_value = new V();}auto old_val_ptr = target->value_ptr.load(std::memory_order_acquire);if (target->value_ptr.compare_exchange_strong(old_val_ptr, new_value, std::memory_order_acq_rel,std::memory_order_relaxed)) {delete old_val_ptr;if (new_entry) {delete new_entry;new_entry = nullptr;}return;}continue;} else {if (!new_entry) {new_entry = new Entry(key);}new_entry->next.store(target, std::memory_order_release);if (prev->next.compare_exchange_strong(target, new_entry,std::memory_order_acq_rel,std::memory_order_relaxed)) {// Insert successif (new_value) {delete new_value;new_value = nullptr;}return;}// another entry has been inserted, retry}} }

bool Get(K key, V **value)

bool Get(K key, V **value) {Entry *prev = nullptr;Entry *target = nullptr;if (Find(key, &prev, &target)) {*value = target->value_ptr.load(std::memory_order_acquire);return true;}return false; }

接口

bool Has(K key) {uint64_t index = key & mode_num_;return table_[index].Has(key);}bool Get(K key, V **value) {uint64_t index = key & mode_num_;return table_[index].Get(key, value);}bool Get(K key, V *value) {uint64_t index = key & mode_num_;V *val = nullptr;bool res = table_[index].Get(key, &val);if (res) {*value = *val;}return res;}void Set(K key) {uint64_t index = key & mode_num_;table_[index].Insert(key);}void Set(K key, const V &value) {uint64_t index = key & mode_num_;table_[index].Insert(key, value);}void Set(K key, V &&value) {uint64_t index = key & mode_num_;table_[index].Insert(key, std::forward<V>(value));}

總結

以上是生活随笔為你收集整理的cyber atomic hash map的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。