REDIS_INTSET

intSet即为:整数集合,整数集合本质上是一块连续内存空间。

编码结构

typedef struct intset {
    // 编码方式
    uint32_t encoding;
    // 集合包含的元素数量
    uint32_t length;
    // 保存元素的数组
    int8_t contents[];
} intset;

前两个属性encodinglength都用于规划这个set。本质上这个set的本体是contents

虽然 contents 被声明为int8_t类型的数组,但是实际上 contents 数组并不保存任何 int8_t 类型的元素,contents 数组的真正类型取决于 intset 结构体里的 encoding 属性的值。

  • 如果 encoding 属性值为 INTSET_ENC_INT16,那么 contents 就是一个 int16_t 类型的数组,数组中每一个元素的类型都是 int16_t;
  • 如果 encoding 属性值为 INTSET_ENC_INT32,那么 contents 就是一个 int32_t 类型的数组,数组中每一个元素的类型都是 int32_t;

以此类推,不同类型的 contents 数组,意味着数组的大小也会不同。

contents的升级

前文提到,contents由encoding进行编码。而encoding编码有多种。

如果现在contents正由int16_t编码,而突然插入int32_t,这时contents需要升级。

即:按新元素的类型(int32_t)扩展 contents 数组的空间大小,然后才能将新元素加入到整数集合里。

在升级时,将所有数字全部转换为对应元素类型,并从后往前整理数据。

在contents升级时,依然要维持整数集合的有序性。

为什么要contents升级

如果统一使用int64_t来保存数据,自然没这么多事,用起来也爽。

但是在业务里有很多情况下用不到这么大的数据量,所以根据需求升级可以节省内存资源

contents不支持降级。