6.整数集合

整数集合

1. 整数集合的实现

整数集合是Redis用于保存整数值的集合抽象数据结构,它可以保存类型为int16_t、int32_t、int64_t的整数值,并且保证集合中不会出现重复元素。

每个intset.h/intset表示一个整数集合:

typedef struct intset{

    // 编码方式
    uint32_t encoding;

    // 集合包含的元素数量
    uint32_t length;

    // 保存元素的数组
    int8_t contents[];
}intset;

contents数组是整数集合的底层实现,各个项在数组中按值的大小从小到大有序排列,并且数组中不包含任何重复项。

length记录整数集合包含的元素数量,是contents数组的长度。

contents数组的真正类型取决于encoding的值:

  1. 如果encoding值为INTSET_ENC_INT16,那么contents是一个int16_t类型的值,数组中的每个项都是一个int16_t类型的整数值。
  2. 如果encoding值为INTSET_ENC_INT32,那么contents是一个int32_t类型的值。
  3. 如果encoding值为INTSET_ENC_INT64,那么contents是一个int64_t类型的值。
一个包含5个int16_t类型整数值的整数集合

2. 升级

当将一个新元素添加到整数集合里面,并且新元素的类型比整数集合现有所有元素的类型都要长时,整数集合需要先升级,然后才能将新元素添加到整数集合里面。

升级整数集合并添加新元素共分为三步:

  1. 根据新元素的类型,扩展整数集合底层数组的空间大小,并为新元素分配空间。
  2. 将底层数组现有的所有元素都转换成与新元素相同的类型,并将类型转换后的元素放置到正确的位上,而且在放置元素的过程中,需要继续维持底层数组的有序性质不变。
  3. 将新元素添加到底层数组里面。

引发升级的新元素的长度总是比整数集合现有所有元素的长度要大,所以这个新元素的值要么就大于所有现有元素,要么就小于所有现有元素。

3. 升级的好处

整数集合升级策略有两个好处:提升整数集合的灵活性;尽可能地节约内存。

3.1 提升灵活性

C语言是静态类型语言,为了避免类型错误,通常不会将两种不同类型的值放到同一个数据结构里面。

整数集合可以通过自动升级底层数组来适应新元素,所以可以随意将int16_t、int32_t、int64_t类型的值添加到集合中,不必担心出现类型错误,这种做法非常灵活。

3.2 节约内存

最简单的做法是直接使用int64_t类型的数组作为整数集合的底层实现,不过这样一来,即使添加到整数集合里的都是int16_t、int32_t类型的值,数组都需要用int64_t保存,从而浪费内存。

整数集合现在做法既可以让集合能同时保存三种不同类型的值,又可以确保升级操作只在有需要的时候进行,尽可能节省内存。

4. 降级

整数集合不支持降级操作。

一旦对数组进行了升级,编码就会一直维持在升级后的状态,如,即使将数组中仅有的int32_t的值删掉,剩下全是int16_t值,那么整数集合的编码仍然是INTSET_ENC_INT32。

5. 整数集合API

函数 作用 时间复杂度
intsetNew 创建一个新的压缩列表 O(1)
intsetAdd 将给定元素添加到整数集合里面 O(N)
intsetRemove 从整数集合中移除给定元素 O(N)
intsetFind 检查给定值是否存在于集合 因为底层数组有序,查找可以通过二分查找进行,所以复杂度为O(logN)
intsetRandom 从整数集合中随机返回一个元素 O(1)
intsetGet 取出底层数组在给定索引上的元素 O(1)
intsetLen 返回整数集合包含的元素个数 O(1)
intsetrawLen 返回整数集合占用的内存字节数 O(1)
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 整数集合(intset)是集合键的底层实现之一,当一个集合值包含整数值元素,并且元素不多,Redis就会使用整数集...
    猪大金阅读 2,944评论 0 0
  • 整数集合(intset)是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时,Redi...
    HRADPX阅读 3,624评论 0 0
  • 整数集合 整数集合(intset)是 Redis 用于保存整数值的集合抽象数据结构, 它可以保存类型为 >int1...
    来年花惜阅读 5,768评论 0 0
  • 整数集合是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时,Redis就会使用整数集...
    Felicia1993阅读 1,616评论 0 0
  • 昨日,一张黄晓明Baby两家人一起过年的家庭聚会照被曝光。照片中Baby身穿一件红色外套坐在妈妈和婆婆中间,素颜出...
    独秀荷花阅读 1,711评论 0 0

友情链接更多精彩内容