前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >共享内存中自建hash的一种方法

共享内存中自建hash的一种方法

作者头像
coderhuo
发布2023-10-21 16:22:40
1120
发布2023-10-21 16:22:40
举报
文章被收录于专栏:coderhuocoderhuo

本文介绍在共享内存中自建hash的一种方法。

下图所示的共享内存有一个writer和多个reader,为了提高数据存取效率,共享内存中的数据需要按hash组织。

共享内存示意图
共享内存示意图

注:本文不讨论writer和和reader之间的同步问题,具体可由信号量、文件锁等方式实现。

初步想法是将整块共享内存划分成一个下标为0~n的数组,如下图所示。数据Record的key经过Hash计算后得到hashcode,然后将该值映射为数组的下标,直接通过下标访问数组,将Record的key和value存储在对应的位置。

分区示意图
分区示意图

但是Hash存在冲突的情况,即两个不同的Record经过Hash映射,得到的下标可能是相同的。

为了处理这种情况,需要将共享内存分区,一部分作为常规的Hash索引区,另一部分作为冲突预留区,用来保存hash冲突的Record。如下图所示,具体比例可以根据业务的数据情况调整,如果冲突较多就保留较大的预留区,否则预留区可以小一点,比如按1:1划分或者2:1划分。

注:冲突较多的时候,可以考虑换hash函数。

冲突区示意图
冲突区示意图

数据写入流程如下:

  • 假设Record1经过Hash映射后落在了下标为0的存储单元,该存储单元当前未被占用,直接存储
  • 接下来Record2经过Hash映射后也落在了下标为0的存储单元,这时候从预留区找一个空闲节点(比如下标为k+1的存储单元),将Record2存储在该空闲节点,并建立下标0到k+1的单向链表(方便后续查找)
  • 一段时间后Record3经过Hash映射后也落在了下标为0的存储单元,这时候再从预留区找一个空闲节点(比如下标为k+n的存储单元),将Record3存储在该空闲节点,并建立从下标0到k+1,再到k+n的单向链表。

最终建立了下图所示的链接关系:

hash链表
hash链表

说明:

  • 如果预留区已经没有空闲存储单元,只能报错了
  • 预留区的空闲节点也可以组织成一个单向链表(空闲存储单元链表),当遇到Hash冲突时从该链表摘取节点,当节点不再使用的时候,再归还到该链表中

从上面的介绍可以看出,其实最终整个数组被划分成了下图所示几个链表:

  • 0~k是常规的Hash索引区
    • Hash函数及映射规则决定了这一区域包含几条链表
    • 这些链表至少包含一个头节点,即使该节点没被占用也不能放到空闲列表中
    • 每条链表的长度是不固定的,默认只包含一个头节点,运行期间动态的增加、删除节点
  • 最后一条链表是为了解决hash冲突预留的节点,运行过程中,会根据需要动态的添加到上面0~k链表的后面,当数据释放的时候,再归还到空闲列表
hash链表抽象示意
hash链表抽象示意

数据读取过程:把key做hash映射,得到对应的数组下标,也就知道了该在哪个链表中找数据,依次遍历对应的链表,比较key是否一致,如果一致就找到了对应的记录。

数据删除过程

  • 先按数据读取流程找到对应的数据存储单元
  • 如果该存储单元不是头节点,直接将该节点从链表中摘除,放到空闲链表中
  • 如果该节点是头节点
    • 该链表只有一个头节点的情况下,直接标记为空闲状态即可
    • 如果链表除了头节点还有其他节点,由于头节点不能摘除,那就把尾节点的数据拷贝到头节点,将尾节点从链表中摘除,放到空闲链表中
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-08-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档