redis数据结构实现 压缩列表(ziplist) - ZhenLinTechnologySalon/- GitHub Wiki

redis数据结构实现--压缩列表(ziplist)

压缩列表(ziplist)是链表键和哈希键的底层实现之一。当链表键或哈希键只有少量列表项,且列表项中是小整数值或短字符串,则会采用压缩列表作为底层实现。


6.1 压缩列表的实现

压缩列表是为了节约内存而开发的,由一系列特殊编码的连续内存块组成的顺序型数据结构。 一个压缩列表可以包含任意多个节点(entry),每个节点保存一个字节数组或一个整数值。

压缩列表的各个组成部分:

压缩列表各个组成部分的详细说明
<style> table th:first-of-type,th:nth-of-type(2),th:nth-of-type(3) { width: 100px; }</style>
属性 类型 长度 用途
zlbytes uint32_t 4字节 记录整个压缩列表占用的字节数:对压缩列表进行内存重分配,或者计算zlend的时候使用
zltail uint32_t 4字节 记录压缩列表表尾节点距离起始地址有多少个字节,使程序无需遍历就能确定表尾节点地址
zllen uint16_t 2字节 记录压缩列表包含的节点数量,当此属性值小于UINT16_MAX(65535)时,该值就是节点数量;当该值等于UINT16_MAX时,节点真实数量需要遍历才能得出
entryX 列表节点 不定 节点,长度由保存的内容决定
zlend uint8_t 1字节 特殊在0xFF(十进制255),用于标记压缩列表的末端

6.2 压缩列表节点构成

压缩列表节点各个组成部分

详解各个组成部分:

6.2.1 previous_entry_length

previous_entry_length以字节为单位,记录了压缩列表中前一个字节的长度,该属性长度可为1字节或者5字节。

  • 如果前一节点长度小于254字节,那么previous_entry_length长度为1字节,:前一节点的长度就保存在这一个字节里面;
  • 如果前一节点长度大于254字节,那么previous_entry_length长度为5字节,其中previous_entry_length的第一字节会被设置为0xFE(十进制254),而之后的四字节保存前一节点的长度。

因为previous_entry_length记录了前一个节点的长度,可以通过当前节点的起始地址计算出前一个节点的起始地址,这也是压缩列表从表尾向表头的实现原理


6.2.2 encoding

记录了content中保存的类型与长度

  • 一字节、两字节或者五字节长,值最高位为00、01、或者10是字节数组编码:这种编码表示节点的content属性保存着字节数组,数组长度由编码去掉最高两位的其他位录。
  • 一字节长,值的最高位为11的是整数编码:这种编码表示content保存的是整数值,整数值类型和长度由编码去除最高两位的其他位记录。

6.2.3 content

content负责保存节点的值,可以保存一个整数值或者一个字节数组。

⚠️ **GitHub.com Fallback** ⚠️