redis数据结构实现 压缩列表(ziplist) - ZhenLinTechnologySalon/- GitHub Wiki
压缩列表(ziplist)是链表键和哈希键的底层实现之一。当链表键或哈希键只有少量列表项,且列表项中是小整数值或短字符串,则会采用压缩列表作为底层实现。
压缩列表是为了节约内存而开发的,由一系列特殊编码的连续内存块组成的顺序型数据结构。 一个压缩列表可以包含任意多个节点(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),用于标记压缩列表的末端 |
压缩列表节点各个组成部分
详解各个组成部分:
previous_entry_length以字节为单位,记录了压缩列表中前一个字节的长度,该属性长度可为1字节或者5字节。
- 如果前一节点长度小于254字节,那么previous_entry_length长度为1字节,:前一节点的长度就保存在这一个字节里面;
- 如果前一节点长度大于254字节,那么previous_entry_length长度为5字节,其中previous_entry_length的第一字节会被设置为0xFE(十进制254),而之后的四字节保存前一节点的长度。
因为previous_entry_length记录了前一个节点的长度,可以通过当前节点的起始地址计算出前一个节点的起始地址,这也是压缩列表从表尾向表头的实现原理
记录了content中保存的类型与长度
- 一字节、两字节或者五字节长,值最高位为00、01、或者10是字节数组编码:这种编码表示节点的content属性保存着字节数组,数组长度由编码去掉最高两位的其他位录。
- 一字节长,值的最高位为11的是整数编码:这种编码表示content保存的是整数值,整数值类型和长度由编码去除最高两位的其他位记录。
content负责保存节点的值,可以保存一个整数值或者一个字节数组。