Redis中当一个集合键只包含整数值元素,并且数量不是很多时,使用整数集合作为底层实现。
1. 定义
- 整数集合
- encoding 集合采用的编码方式:int16_t, int32_t, int64_t
- length contents中包含整数的个数
- contents 用于存储整数集合,通过encding来确定每个数字需要多少byte,如:int16_t, 表示每个数字占16位,若集合有3个元素,那么 contents的长度就位48 。
1 | typedef struct intset { |
2. 升级
由于intset的结构方式,当添加的整数类型大于当前集合的编码方式时,需要对集合进行升级。
- 根据新元素的类型,重新计算需要的内存空间大小,并对整数集合的contents进行扩展。
- 将contents内原有的数据,放到新的位置,从后边开始,这样不会导致前面的数据不可用。
- 将新元素添加到集合中。
假设:
集合中有4个元素12, 27, 35, 68,而目前采用的编码方式为int16_t,contents的大小为4x2=8字节,现在要添加一个 66666,超过了int16_t所能表示的范围,所以需要int32_t来存储,此时需要对集合进行升级,重新计算所需要的空间(4+1)x4 = 20字节,所以先扩展内存空间,再移动68,35,27,12到指定位置,然后添加新元素。
3. 源码剖析
- 升级并添加
1 | // intrev32ifbe 用于大小端转换 |
- 添加元素
1 | /** |
- 删除元素
1 | intset *intsetRemove(intset *is, int64_t value, int *success) { |