整数集合
整数集合是集合键的底层实现之一,当一个集合只包含整数数值元素,并且这个集合的元素数量不多时,redis就会使用整数集合作为集合键的底层实现。
整数集合的实现
整数集合是redis用于保存整数值的集合抽象数据结构,它可以保存类型为int16,int32和int64的整数值,并且保证集合中不会出现重复元素。
整数集合的结构如下:
typedef struct intset {
//编码方式
unit32_t encoding;
//集合包含的元素数量
unit32_t length;
//保存元素的数数组
int8_t contents[];
}intset;
[ ] content数组是整数集合的底层实现,整数集合的每个元素都是contents数组的一个项,各个项在数组中按值得大小从小到大有序的排列,并且不包含任何重复项。代码中的int8_t不是固定的,时机的类型是由encoding的值决定的。
[ ] length属性记录了整数集合包含的元素数量。
升级
当我们需要将一个新元素添加到整数集合里面,并且新的元素的类型比整数集合现有的所有元素都要长时,整数集合需要先进行升级,然后才能将新元素添加到整数集合里面。
步骤:
- 根据新元素的类型,扩展整数集合底层数组的空间大小,并为新元素分配空间。
- 将底层现有的所有元素都转换成与新元素相同的类型,并将类型转换后的元素放置到正确的位置上,放置过程中需要维持有序性不变。
- 将新元素添加到底层数组中。
升级的好处
提升灵活性
不限制数组的元素类型,可以灵活的转换。
节约内存
当我们的数据较小时,可以使用16位整数存储;当我们的数据较大时,可以使用64位存储;不会出现一刀切的情况。合理运用内存
降级
数组集合不支持降级,一旦对数组进行了升级,编码就会一直保持升级后的状态。
整数集合API
函数 | 作用 | 事假复杂度 |
---|---|---|
intsetNew | 创建一个新的集合数组 | O(1) |
intsetAdd | 将给定的元素添加到整数集合中 | O(N) |
intsetRemove | 从整数集合中移除给定元素 | O(N) |
intsetFind | 检查给定值是否存在于集合 | 因为底层有序,查找可以通过二分查找法来进行,复杂度为O(logN) |
intsetRandom | 从整数集合中随机返回一个元素 | O(1) |
intsetGet | 取出底层数组在给定索引上的元素 | O(1) |
intsetLen | 返回整数集合包含的元素个数 | O(1) |
intsetBlobLen | 返回整数集合占用的内存字节数 | O(1) |