Chapter7 压缩列表
列表键和哈希键的底层实现之一(列表键只包含少量元素,且元素为小整数或较短字符串;而哈希键之包含少量键值对,且每个键值对的key和value都是小整数或较短字符串)。
为了节约内存。
压缩列表的组成
一系列特殊编码的连续内存块组成的顺序型(sequential)数据结构,包含多个节点entry,每个entry保存一个字节数组或一个整数。
内存组织:
具体含义:
压缩列表节点的组成
每个节点保存一个字节数组或者一个整数值,由 previous_entry_length 、 encoding 、 content 三个部分组成。
保存的字节数组可以是以下三种长度的其中一种:
- 长度小于等于 63 (2^{6}-1)字节的字节数组;
- 长度小于等于 16383 (2^{14}-1) 字节的字节数组;
- 长度小于等于 4294967295 (2^{32}-1)字节的字节数组;
而整数值则可以是以下六种长度的其中一种:
- 4 位长,介于 0 至 12 之间的无符号整数;
- 1 字节长的有符号整数;
- 3 字节长的有符号整数;
- int16_t 类型整数;
- int32_t 类型整数;
- int64_t 类型整数。
节点内存组织:
具体含义:
- previous_entry_length:前一个节点entry的长度字节数,相当于向前指针;
- 长度:1或5字节
- 前一节点长度<254:1字节;
- 前一节点长度>=254:5字节,且第一字节设为0xFE(即254),后4个字节保存真正的长度数据;
- encoding:节点content属性所保存数据的类型和长度,根据字节数据和整数两种数据类型可做如下解析
- content:保存节点真正的数据,由encoding属性决定如何解释;
连锁更新问题
特殊情况:
- 插入:多个连续的、长度介于250~253字节直接的节点e1至eN(previous_entry_length属性都为1个字节);此时在e1前插入一个长度>=254字节的节点,则需更新e1的previous_entry_length属性(由1字节长度变为5字节),导致e1长度>=254,于是连锁更新e2、e3...eN。
- 删除:在两个节点big(长度>=254)和small(长度<254)之后紧跟着多个连续的、长度介于250~253字节直接的节点e1至eN(previous_entry_length属性都为1个字节);此时删除small,则需更新e1的previous_entry_length属性(由1字节长度变为5字节),导致e1长度>=254,于是连锁更新e2、e3...eN。
连锁更新最坏情况下需要对压缩列表做N次空间重分配操作,而每次分配的最坏复杂度为O(N),所以连锁更新最坏情况为O(N^2)。但是可预见的是对性能影响不大:
- 出现上述两种情况的概率很小;
- 即使出现,只要更新的节点不多,性能也不会有影响;
时间: 2024-10-27 16:58:51