Redis 基本数据类型 Set | 青训营

63 阅读2分钟

Set

Set 是 Redis 中的单列集合,满足下列特点:

  • 不保证有序性
  • 保证元素唯一(可以判断元素是否存在)求交集、并集、差集

HashTable,也就是 Redis 中的 Dict,不过 Dict 是双列集合(可以存键、值对)

Set 是 Redis 中的集合,不一定确保元素有序,可以满足元素唯一、查询效率要求极高。

  • 为了查询效率和唯一性,set 采用 HT 编码(Dict)。Dict 中的 key 用来存储元素,value 统一为 null。
  • 当存储的所有数据都是整数,并且元素数量不超过 set-max-intset-entries 时,Set 会采用 IntSet 编码,以节省内存。

判断是不是整数,如果是用 intset 编码,否则用 dict

添加数据的逻辑,还是挺清晰的

intset 内存图

dict 内存图

intset

结构

IntSet 是 Redis 中 set 集合的一种实现方式,基于整数数组来实现,并且具备长度可变、有序等特征。

encoding 包含三种模式,表示存储的整数大小不同

为了方便查找,Redis 会将 intset 中所有的整数按照升序依次保存在 contents 数组中,结构如图:

现在,数组中每个数字都在 int16_t 的范围内,因此采用的编码方式是 INTSET_ENC_INT16,每部分占用的字节大小为:

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

为什么需要保存 encoding 大小

因为可以通过下面的公式通过 index 快速找到目标地址

扩容

我们向该其中添加一个数字:50000,这个数字超出了 int16_t 的范围,intset 会自动升级编码方式到合适的大小。以当前案例来说流程如下:

源码

插入函数,判断当前编码值和需要插入的元素的编码值

如果新元素是大于零的,从后开始搬运后插入最后一个位置,否则插入第一个位置

通过二分查找查看是否需要插入