Skip to content

Latest commit

 

History

History
66 lines (42 loc) · 2.57 KB

ch6.md

File metadata and controls

66 lines (42 loc) · 2.57 KB

整数集合(intset)是集合键的底层实现之一,当一个集合只包含整数值元素,并且数量不多时,Redis采用整数集合作为集合键的底层实现。

6.1 整数集合的实现

整数集合,可以保存int16_t、int32_t或者int64_t的整数值,且元素不重复,intset.h/intset结构表示一个整数集合:

typedef struct intset {
  uint32_t encoding; // 决定contents保存的真正类型
  uint32_t length;
  int8_t contents[]; // 各项从小到大排序
} inset;

five-int16

上图中,contents数组的大小为sizeof(int16_t) * 5 = 80位。

6.2 升级

每当添加一个新元素到整数集合中,且新元素的类型比现有所有元素的类型都要长时,整数集合需要先升级(update),然后才能添加新元素:

  1. 根据新元素的类型,扩展底层数组的空间大小,并未新元素分配空间。
  2. 将底层数组现有元素转换成与新元素相同的类型,并放置在正确的位置上(从后向前遍历)。放置过程中,维持底层数组的有序性质不变。
  3. 将新元素添加到底层数组里。

因为每次升级都可能对所有元素进行类型转换,所以复杂度为O(N)

PS. 因为引发升级的新元素长度比当前元素都大,所以它的值要么大于当前所有元素,要么就小于。前种情况放置在底层数组的末尾,后种情况放置在头部。

6.3 升级的好处

升级有两个好处

  1. 提升整数集合的灵活性

    我们可以随意地将int16_t、int32_t添加到集合中,不必担心出现类型错误,毕竟C是个静态语言。

  2. 尽可能解约内存

    避免用一个int64_t的数组包含所有元素

6.4 降级

整数集合不支持降级

6.5 整数集合API

函数 作用 时间复杂度
intsetNew 创建一个新的整数集合 O(1)
intsetAdd 添加指定元素 O(N)
intsetRemove 移除指定元素 O(N)
intsetFind 检查给定值是否存在 因为底层数组有序,所以O(logN)
insetRandom 随机返回一个元素 O(1)
intsetGet 返回给定索引上的元素 O(1)
intsetLen 返回元素个数 O(1)
intsetBlobLen 返回占用的内存字节数 O(1)

导航

目录

上一章:5. 跳跃表

下一章:7. 压缩列表