整体结构

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相关推荐

  1. 数据结构(55) 散列表(哈希表,hash table,hash map)

    目录 1.散列表的基本概念 2.散列函数的构造方法 3.常用的散列函数 3.1.直接定址法 3.2.除留余数法 3.3.数字分析法 3.4.平方取中法 3.5.乘法哈希法(The Multiplica ...

  2. nssl1211-好文章【字符串hash,map】

    正题 题目大意 求长度为n个一个字符串长度为m不同的子串个数 解题思路 用字符串hash判断字符串是否相同,然后时间复杂度O(n2)O(n^2)O(n2),然后我们因为自然溢出所以不能开桶,那就开ma ...

  3. Rust之常用集合(三):哈希映射(Hash Map)

    开发环境 Windows 10 Rust 1.66.0 VS Code 1.74.2 项目工程 这里继续沿用上次工程rust-demo 在哈希图中存储带有关联值的键 我们常见的集合中的最后一个是哈希映 ...

  4. atomic、锁、多线程

    [TOC] @(iOS开发学习)[温故而知新] 一:atomic是线程安全的吗 atomic所说的线程安全只是保证了属性的getter和setter存取方法的线程安全,并不能保证整个对象是线程安全的. ...

  5. 『每周译Go』Go sync map 的内部实现

    目录 引言 a. 简单介绍并发性及其在此上下文中的应用 sync.RWMutex 和 map 一起使用的问题 介绍 sync.Map a. 在哪些场景使用 sync.Map? sync.Map 实现细 ...

  6. Java之数组array和集合list、set、map

    2019独角兽企业重金招聘Python工程师标准>>> 世间上本来没有集合,(只有数组参考C语言)但有人想要,所以有了集合   有人想有可以自动扩展的数组,所以有了List   有的 ...

  7. java list接口为何要重新声明collection接口的方法_JAVA Collection接口中List Map 和Set的区别(转)...

    Java中的集合包括三大类,它们是Set(集).List(列表)和Map(映射),它们都处于java.util包中,Set.List和Map都是接口,它们有各自的实现类.Set的实现类主要有HashS ...

  8. K:hash(哈希)碰撞攻击

    相关介绍:  哈希表是一种查找效率极高的数据结构,很多语言都在内部实现了哈希表.理想情况下哈希表插入和查找操作的时间复杂度均为O(1),任何一个数据项可以在一个与哈希表长度无关的时间内计算出一个哈希值 ...

  9. java lList Map Set总结

    @RequestMapping("/test")public void test(){//List 模块/*** Arraylist 基于数组实现 非线程安全 效率高 查找快 增删 ...

最新文章

  1. Nginx源码分析:epoll事件处理模块概述
  2. C# .net中json字符串和对象之间的转化方法
  3. [链接]C++和Python版本的委托
  4. H3C 使用命令视图
  5. 深度学习试题_高中生物:今年高考试题3点显著变化及5个备考建议!不看准吃亏...
  6. 让SH/BAT脚本定位到运行目录的相对位置,实现其脚本可在任意运行目录下被正确执行...
  7. Web Components 系列(五)—— 详解 Slots
  8. appium python很慢_appium+python自动化测试遇到的坑及处理方案
  9. 佐客牛排机器人餐厅_3分钟出餐!全球首家机器人餐厅开业
  10. ssdp java_SSDP协议 - 实施
  11. 【AI视野·今日CV 计算机视觉论文速览 第192期】Thu, 6 May 2021
  12. 《 阿房宫赋》古文鉴赏
  13. WEB财务报表设计器的实现
  14. 练习绕口令快速提高语言表达能力(收藏)
  15. Yoga Book YB1-X91F 重装win10系统后键盘没有震动的解决办法
  16. ajax导致服务端线程粘滞,解决js ajax同步请求造成浏览器假死的问题
  17. 微信-H5界面跳转至公众号关注界面问题
  18. 旧金山第二天: OOW 开始
  19. unity 陶瓷质感_一种基于Unity3D的虚拟陶瓷设计方法与流程
  20. spring中的注解和xml配置文件中配置对应总结

热门文章

  1. python提取txt数据到excel_python 读取txt中每行数据,并且保存到excel中的实例
  2. 带虚函数的类的sizeof分析
  3. JavaSE——异常处理(异常简介、try-catch-finally、throws、throw)
  4. PyQt5 快速开发 与 实战
  5. find 和 xargs 和 locate
  6. Kali Linux 和 渗透测试
  7. android support library github,Android Support Library 之 夜间模式
  8. 外设驱动库开发笔记20:BME280压力湿度温度传感器驱动
  9. Modbus协议栈应用实例之六:Modbus ASCII从站应用
  10. 赶紧看一下mysql8.0版本的新特性,你的数据库是不是该升级了