redis底层数据结构:IntSet

IntSet

IntSet是redis中set集合的一种实现方式,基于整数数组来实现,并且具备长度可变、有序等特征。
结构如下:
在这里插入图片描述

  • encoding : 32位,编码方式,支持16位,32位,64位整数
  • length: 32位,元素个数
  • contents:8位的整数数组,保存集合数据(可以看到才8位,并没有遵循c语言的存储规范,存储数据的大小由encoding控制)

其中encoding 包含三种模式,表示存储的整数大小不同
在这里插入图片描述
为了方便查找,redis会将intset中所有的整数按升序排序依次保存到contents数组中,结构如图
在这里插入图片描述
现在数据都在16位范围内,因此encoding使用的是INTSET_ENC_INT16,每部分占用的字节数

  • encoding: 4字节
  • length: 4字节
  • contents: 2字节*3=6字节

数组每个元素都是按照同一的编码格式的,这样是为了方便intset根据数组角标去寻址,c语言中数组是指针,指针是一个无符号8位的整数,只需要知道编码格式,就能很方便的找到数组中的每个元素
在这里插入图片描述

如:5这个元素的起始地址是0x001, 那么10对应的是0x001 + 2个字节 = 0x003, 20对应的就是0x003 + 2字节 = 0x005,数组的角标是从0开始的,对应的元素查找的时候只需 起始地址 + 字节数 * 角标 就可以找到对应的元素。

IntSet升级

现在,假设有个intset集合,元素位{5, 10, 20},采用的编码是INTSET_ENC_INT16,则每个整数占2个字节
在这里插入图片描述
我们向其中添加一个数字:50000,超出了int16的范围,intset会自动升级编码到合适的大小

  • 升级编码到INTSET_ENC_INT32,每个整数占4个字节,并按照新的编码方式及元素个数进行扩容
    在这里插入图片描述
  • 倒叙依次将数组中的元素拷贝到扩容的位置(为什么要倒叙,例如:5现在占4个字节,势必会覆盖掉10的位置,导致10的元素找不到了,所以采用倒叙)
    在这里插入图片描述
  • 将待添加的元素放入数组末尾
    在这里插入图片描述
  • 最后将encoding,修改为INTSET_ENC_INT32,将length修改位4

IntSet查询

IntSet检索是根据二分法查找的,因为IntSet是有序的,可以根据二分法查找。

总结

IntSet可以看作是特殊的整数数组,具备一些特点:

  • Intset元素是唯一,有序的
  • 具备类型升级机制,可以节省内存空间
  • 底层采用二分查找的方式来查询
  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值