使用场景:
当一个列表键只包含少量列表项,且同时列表项要么是小整数值,要么是比较短的字符串时,会使用压缩列表做列表键的底层实现。
压缩列表的结构:
- zlbytes:4字节:记录整个压缩列表占用的内存字节数
- zltail:4字节:记录压缩列表表尾节点距压缩列表起始地址有多少字节
- zllen:2字节:记录压缩列表包含的节点数量
- entryX:包含压缩列表的各个节点
- zlend:特殊值0xff:标记压缩列表的末端
压缩列表节点的构成:
压缩列表可以存储字节数组和整数值,其中,整数值要求可以是6种长度之一:
- 4位长:介于0到12之间,无符号整数
- 一字节长有符号整数
- 三字节长有符号整数
- int16_t类型整数
- int32_t类型整数
- int64_t类型整数
字节数组必须是以下三种长度之一:
7. 长度小于等于63字节的字节数组
8. 长度小于等于16383字节的字节数组
9. 长度小于等于4294967295字节的字节数组
压缩列表节点主要有三个部分:
- previous_entry_length: 以字节为单位,记录压缩列表前一个节点的长度,previous_entry_length可以为一字节或五字节长度(前一个节点长度小于254字节,则previous_entry_length使用一字节;反之,若一个节点长度大于等于254字节,previous_entry_length用五字节记录长度,其中第一字节全部置高位,剩下四个字节记录长度)
- encoding属性:记录节点content属性保存数据的类型和长度
encoding属性可能为1字节,2字节,5字节长,当节点保存的时字节数组时encoding可能为一字节(开头为00),二字节(开头为01),五字节(开头为10);当节点保存的是整数时,encoding为一字节(开头为11,后面的几位分别代表几种具体的类型)如果整数是4位长:介于0到12之间,无符号整数,那就会直接引用encoding属性记录这个值(encoding前4位为高位,后四位记录这个值),这个节点将会没有content属性(1111xxxx,xxxx代表这个值) - content属性:负责保存节点的值,他的类型和长度由encoding决定
连锁更新
连锁更新主要指多个连续的250到253个字节长的节点e1-en组成压缩列表时,由于头部新添加了一个长度大于254字节的列表节点(或者删除了一个节点导致e1的前一个节点由小于等于254字节的节点变成了大于254字节的另一个节点),在这种情况下,必须要从e1到en每一个节点都做空间重分配操作(扩展空间),但这种情况并不常见(触发条件比较苛刻),所以对性能影响并不大。