压缩列表是列表键和哈希键的底层实现之一。
只包含少量列表项,且都为小整数或者短字符串那么redis会将压缩列表作为列表键使用
压缩列表的构成
zlbytes: uint32_t类型占四个字节,记录整个压缩列表占用的内存字节数。在对压缩列表内存重分配或者计算zlend的位置时使用。
zltail:uint32_t类型占四个字节,记录表尾节点距离(不是zlend,是entryN)压缩列表的起止地址有多少字节。
zllen:uint16_t类型占两个字节,记录压缩列表中的节点数量,当当前值等于65535,需要遍历才能出长度。
entryX:列表节点,内存长度不定。
zlend:uint8_t类型占一个字节,特殊值0xFF,用于标记压缩列表末端。
压缩列表节点的构成(entryX)
previous_entry_length:记录了压缩列表中前一个节点的长度。
如果前一个节点的长度小于254字节,那么长度为1字节。
如果大于等于254字节,则长度为5字节,其中第一个字节会被设置为0xFE,确保知道多长,后面四个字节保存前一节点的长度。
因为记录了前一个字节的长度,所以可以通过指针运算根据当前节点的起始地址计算出前一个节点的起始地址。
encoding:记录了节点的content属性所保存数据的类型以及长度。可以一字节(<=63)两字节(<=16383)五字节长(<=2^38),最高位为00,01,10,确保知道encoding多长。
content:保存节点的值。
连锁更新
添加新节点时可能会让后一个节点的previous_entry_length发生变化导致后面一连串发生变化。
所以连锁更新的最坏复杂度为O(n^2),但几率很低,平均复杂度为O(n)。