• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

redis源码阅读之intset

redis 海叔叔 22小时前 4次浏览 已收录 0个评论

今天来讲讲redis当中set的一种实现形式intset,顾名思义,其应用场景只是在集合当中只包含整数值并且元素数量不多时,set才会采用的一种实现方式。
其存储结构如下所示:

其中三个宏定义表示的是encoding字段的可能取值,分别对应intset中的contents数组的三种不同的解析方式(16位整数,32位整数,64位整数)。这里需要注意的是由于不同的机器本地的endian可能不同,redis使用了endianconv.h文件中的函数对这方面进行了统一。在contents中存放的实际数字时按照从小到大的顺序排列好的,并且没有重复项。
整个intset里面比较好玩的就是插入元素了。由于有三种不同的编码方式,当插入的新元素所占的空间较大,大到目前intset自身的编码无法承载这一数据的时候,intset就会根据新插入的值得大小,将原有的inset的encoding变为需要的,其具体步骤如下:
根据插入的元素类型,适当扩展intset所占的空间
在维持低层数组存储数据不变的基础上,按照从后到前的顺序(避免覆盖)拷贝到新的位置上
将新添加的元素插入到intset当中
其中插入代码如下所示:

在这个函数当中,首先判断了插入值的编码,若应该分配较大的空间,直接调用update函数

如果当前intset当中已经有该元素的话,直接返回。若没有,需要找到应该插入的位置,移动其后面的元素,再将该值插入到应该插入的位置。
删除操作的话,逻辑就是能否找到,若找到的话,就直接将后面的元素移动过来,直接覆盖即可

这里面需要提醒诸位的是:删除元素的时候没有降级操作!!!个人猜测的原因为:如果删除一个元素就要从头到尾检查当前的encoding是否过大的话,就会造成不必要的消耗,还不如让其多占用点内存了~~~


喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址