Redis——整数集合
整数集合是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时,Redis就会使用整数集合作为集合键的底层实现
整数集合的实现
整数集合(intset)是Redis用于保存整数值的集合抽象数据结构,可以保存类型为int16_t、int32_t或者int64_t的整数值,并且保证集合中不会出现重复元素
- 每个
intset.h/intset
结构表示一个整数集合
typedef struct intset {
//整数集合中元素的编码方式
uint32_t encoding;
//整数集合的元素数量,即contents数组的长度
uint32_t length;
//保存元素的数组,数组中的元素从大到小有序排列,不会出现重复元素
//虽然contents数组被声明为int8_t类型,但数组中的元素的类型由encoding的值决定
//encoding的取值为int16_t、int32_t和int64_t中一种
int8_t contents[];
}intset;
升级
每当向整数集合中添加新元素时,会对新元素的值进行判断,如果该值超过了整数集合中所有元素的编码形式的取值范围,那么就会对整数集合中的所有元素先进行升级,也就是将集合中的元素的编码方式转换为更大的编码方式,再将新元素加入的新编码方式的整数集合中,并且整数集合不支持降级行为
升级:int16_t --> int32_t --> int64_t
升级的好处
- 提升灵活性:整数集合中只保存同一编码
encoding
的数据,添加不同的编码方式的数据会自动进行升级,不必担心程序的类型出错 - 节约内存:如果集合中的数据只需要使用16位就可以表示了,那么Redis会自动使用
int16_t
,只有在元素需要更高位数来表示时才会进行编码转换
整数集合API
函数 | 作用 |
---|---|
intsetNew | 创建一个新的整数集合 |
intsetAdd | 将给定元素添加到整数集合中 |
intsetRemove | 从整数集合中删除给定元素 |
intsetFind | 检查给定元素是否在整数集合中 |
intsetGet | 取出整数集合中指定索引上的元素 |
intsetLen | 获取整数集合的长度 |
总结
- 整数集合是集合键的底层实现之一
- 整数集合的底层实现是数组,并且这个数组中的元素有序、不重复,在需要时会根据新添加的元素进行编码升级改变整数集合的类型
- 升级操作为整数集合带来操作上的灵活性,并且尽可能节约了内存
- 整数集合只支持升级操作,不支持降级操作