redis底层数据结构已完结👏👏👏:
IntSet是一个存储整数值的集合,内部使用有序、无重复的数组保存数据。优点:节省内存空间。高效的查找、插入和删除操作。使用场景: 在集合键只包含整数值且数量较少时使用。
typedef struct intset {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;
#define INTSET_ENC_INT16 (sizeof(int16_t))
#define INTSET_ENC_INT32 (sizeof(int32_t))
#define INTSET_ENC_INT64 (sizeof(int64_t))
encoding
: 数据编码,表示intset中的每个数据元素用几个字节来存储。它有三种可能的取值:INTSET_ENC_INT16
表示每个元素用2个字节存储,INTSET_ENC_INT32
表示每个元素用4个字节存储,INTSET_ENC_INT64
表示每个元素用8个字节存储。因此,intset中存储的整数最多只能占用64bit。
length
: 表示intset中的元素个数。encoding和length两个字段构成了intset的头部(header)。
contents
: 是一个柔性数组(flexible array member),表示intset的header后面紧跟着数据元素。这个数组的总长度(即总字节数)等于encoding * length。柔性数组在Redis的很多数据结构的定义中都出现过(例如sds, quicklist, skiplist),用于表达一个偏移量。contents需要单独为其分配空间,这部分内存不包含在intset结构当中
说明:
encoding
= 2, length
= 0。encoding
不变,值还是2。encoding
必须升级到INTSET_ENC_INT32(值为4),即用4个字节表示一个元素。encoding
字段的4个字节应该解释成0x00000004,而第5个数据应该解释成0x000186A0 = 100000。intset与ziplist相比:
当在一个int16类型的整数集合中插入一个int32类型的值,整个集合的所有元素都会转换成32类型。 整个过程有三步: