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