1.概述
整数集合(intset)并不是一个基础的数据结构,而是Redis自己设计的一种存储结构,是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时, Redis就会使用整数集合作为集合键的底层实现。
2.整数集合的实现
2.1 源码:
//每个intset结构表示一个整数集合
typedef struct intset{
//编码方式
uint32_t encoding;
//集合中包含的元素数量
uint32_t length;
//保存元素的数组
int8_t contents[];
} intset;
- contents数组是整数集合的底层实现,整数集合的每个元素都是 contents数组的个数组项(item),各个项在数组中按值的大小从小到大有序地排列,并且数组中不包含任何重复项。
- length属性记录了数组的长度。
- intset结构将contents属性声明为int8_t类型的数组,但实际上 contents数组并不保存任何int8t类型的值, contents数组的真正类型取决于encoding属性的值。encoding属性的值为INTSET_ENC_INT16则数组就是uint16_t类型,数组中的每一个元素都是int16_t类型的整数值(-32768——32767),encoding属性的值为INTSET_ENC_INT32则数组就是uint32_t类型,数组中的每一个元素都是int16_t类型的整数值(-2147483648——2147483647)。
2.2升级
如果当前集合为一int16_t类型的整数集合,集合中的元素它们按照从小到大的顺序依次排列。这个时候我们思考一个问题。如果这个时候存入一个int32_t类型的整数会怎么样?内存溢出?这个时候就要提到整数集合的升级。
2.3 降级
整数集合不支持降级操作,一旦对数组进行了升级,编码就会一直保持升级后的状态
2.4 时间复杂度
操作 | 时间复杂度 |
---|---|
创建一个新的整数集合 | O(1) |
添加指定元素到集合 | O(N) |
移除指定元素 | O(N) |
判断指定元素是否在集合中 | O(logN) |
随机返回一个元素 | O(1) |
取出在指定索引上的元素 | O(1) |
返回集合包含的元素个数 | O(1) |
返回集合占用的内存字节数 | O(1) |
3.总结
- 整数集合是Redis自己设计的一种存储结构,集合键的底层实现之一。
- 整数集合的底层实现为数组,这个数组以有序、无重复的方式保存集合元素,在有需要时,程序会根据新添加元素的类型,改变这个数组的类型。
- 升级操作为整数集合带来了操作上的灵活性,并且尽可能地节约了内存。
- 整数集合只支持升级操作,不支持降级操作。