1、背景
redis的intset(整数集合)是一种用于存储整数的紧凑数据结构,redis的set类型数据在数据量少并且全部为证书的时候就采用此种结构,接下来就来讲解一下intset的底层结构(redis版本6.2.18)。
2、整数集合
【1】底层结构
intset的底层结构如下:
typedef struct intset {
uint32_t encoding; //编码方式
uint32_t length; //集合包含的元素数量
int8_t contents[]; //保存元素的数组
} intset;
需要注意的是,contents数组存储真正的类型和encoding的属性有关,encoding的属性值定义如下:
#define INTSET_ENC_INT16 (sizeof(int16_t))
#define INTSET_ENC_INT32 (sizeof(int32_t))
#define INTSET_ENC_INT64 (sizeof(int64_t))
contents数组的存储规则为:
1、encoding属性值为INTSET_ENC_INT16,那么contents就是一个int16_t类型的数组,数组中每一个元素的类型都是int16_t。
2、encoding属性值为INTSET_ENC_INT32,那么contents就是一个int32_t类型的数组,数组中每一个元素的类型都是int32_t。
3、encoding属性值为INTSET_ENC_INT64,那么contents就是一个int64_t类型的数组,数组中每一个元素的类型都是int64_t。
【2】特性
intset的特性如下:
特性 | 描述 |
---|---|
有序性 | 所有元素按照从小到大的顺序排列 |
唯一性 | 集合中不允许重复元素 |
动态编码 | 根据元素大小自动升级编码(16/32/64位) |
内存紧凑 | 连续存储,无额外指针开销 |
二进制安全 | 直接存储整数值而非字符串表示 |
自动升级 | 当添加的元素超过当前编码范围时自动升级编码 |
【3】优缺点
intset优缺点如下:
优点 | 缺点 |
---|---|
内存效率高,无额外指针开销 | 插入操作可能触发编码升级,删除操作不会触发编码降级,性能开销大 |
有序存储,二分查找效率高(O(logN)) | 只适合存储整数,不支持其他数据类型 |
对小整数集合非常高效 | 当元素数量大时,不如哈希表或跳表高效 |
自动处理整数范围,无需手动管理 | 升级编码时可能需要重新分配内存 |