REDIS_INTSET
intSet即为:整数集合,整数集合本质上是一块连续内存空间。
编码结构
typedef struct intset {
// 编码方式
uint32_t encoding;
// 集合包含的元素数量
uint32_t length;
// 保存元素的数组
int8_t contents[];
} intset;
前两个属性encoding
和length
都用于规划这个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不支持降级。