Redis设计与实现_7.压缩列表

压缩列表的构成

压缩列表是列表键和哈希键的底层实现之一,当一个列表键只包含少量列表项,并且每个列表项都是小整数或较短字符串,则用压缩列表作为底层实现

压缩列表是为了节约内存而开发的,是由一系列特殊编码的连续内存块组成的顺序型数据结构

  • zlbytes:记录整个压缩列表所占用的内存字节数,在内存重分配或zlend位置时使用
  • zltail:记录压缩列表表尾节点距压缩列表的起始地址有多少字节,通过该偏移量,可无须遍历整个压缩列表就可以确定表尾节点的地址
  • zllen:记录了压缩列表包含的节点数量
  • entryX:压缩列表包含的各个节点,节点长度由节点包含的内容决定
  • zlend:特殊值oxFF,用于标记压缩列表的末端

压缩列表节点的构成

previous_entry_length

以字节为单位,记录压缩列表前一个节点的长度。所以可以通过指针运算,根据当前节点的起始地址得到前一个节点的起始地址,用于从表尾到表头的遍历

指向表尾节点的指针 可以通过压缩列表的起始地址的指针加上zltail

encoding

记录节点的content属性所保存数据的类型及长度

content

负责保存节点的值,值的类型和属性由encoding决定

连锁更新

如果在压缩列表中,有多个介于250-153字节的节点e1-eN,记录这些节点的长度只需要1字节长的previous_entry_length,所以e1-eN所有节点的previous_entry_length都是1字节长

但如果将一个大于254字节的新节点new加入压缩列表的头节点,则new成为e1的前置节点。而这样e1的previous_entry_length属性不足以保存new的长度,所以进行空间重分配,变成5字节大小

这样e1的长度大于254字节了,e2的previous_entry_length也不足以保存e1的长度,也扩展成5字节大小。这样就进行连续多次空间扩展,即连锁更新

删除节点也会引发连锁更新

连锁更新在最坏情况下需要对压缩列表进行N次空间重分配操作,每次操作最坏O(N),所以连锁更新最坏时间复杂度为 O ( N 2 ) O(N^2) O(N2).

但是发生的机率比较低:1. 恰好有多个连续的,长度介于250-153字节的节点的情况并不多见 2. 即使出现连锁更新,只要被更新的节点数量不多,就不会对性能有影响所以平均复杂度为O(N)

连锁更新,只要被更新的节点数量不多,就不会对性能有影响所以平均复杂度为O(N)

猜你喜欢

转载自blog.csdn.net/weixin_42249196/article/details/108272280