一 ziplist简介以及应用
ziplist称之为压缩链表,顾名思义,压缩链表有压缩节省空间的语义。回想redis另外一种链表:双向链表,每个节点都需要prev、next指针来指向前后节点,如何数据只占1字节,大量的此类数据会造成空间上的浪费。因此redis提出了另外一种更具有空间效率的链表:压缩链表,压缩链表则没有这两个指针,压缩链表含有两个数,一个代表前一个节点的长度,有一个表示当前节点的长度,最少只需2个字节,相比双向链表节省了很多空间。
压缩链表是列表键和哈希键的底层实现之一。当一个列表键只包含少量列表项,并且每个列表项要么是小整数值,要么就是长度较短的字符串,那么Redis就会使用压缩链表来做列表键的实现。
二 一个例子
虽然注释已经详细说明了ziplist的设计思路,但是ziplist的代码较难理解,不妨先来看一个例子:
创建一个空的ziplist链表
加入了第1个节点"abcde"以后
加入了第2个节点"ABC"以后(加在最后)
加入了第3个节点"10"以后(加在最前面)
三 ziplist实现
先看一下作者对ziplist的一些讲解
/* The ziplist is a specially encoded dually linked list that is designed
* to be very memory efficient.
*
* Ziplist 是为了尽可能地节约内存而设计的特殊编码双端链表。
*
* It stores both strings and integer values,
* where integers are encoded as actual integers instead of a series of
* characters.
*
* Ziplist 可以储存字符串值和整数值,
* 其中,整数值被保存为实际的整数,而不是字符数组。
*
* It allows push and pop operations on either side of the list
* in O(1) time. However, because every operation requires a reallocation of
* the memory used by the ziplist, the actual complexity is related to the
* amount of memory used by the ziplist.
*
* Ziplist 允许在列表的两端进行 O(1) 复杂度的 push 和 pop 操作。
* 但是,因为这些操作都需要对整个 ziplist 进行内存重分配,
* 所以实际的复杂度和 ziplist 占用的内存大小有关。
*
* ----------------------------------------------------------------------------
*
* ZIPLIST OVERALL LAYOUT:
* Ziplist 的整体布局:
*
* The general layout of the ziplist is as follows:
* 以下是 ziplist 的一般布局:
*
* <zlbytes><zltail><zllen><entry><entry><zlend>
*
* <zlbytes> is an unsigned integer to hold the number of bytes that the
* ziplist occupies. This value needs to be stored to be able to resize the
* entire structure without the need to traverse it first.
*
* <zlbytes> 是一个无符号整数,保存着 ziplist 使用的内存数量。
*
* 通过这个值,程序可以直接对 ziplist 的内存大小进行调整,
* 而无须为了计算 ziplist 的内存大小而遍历整个列表。
*
* <zltail> is the offset to the last entry in the list. This allows a pop
* operation on the far side of the list without the need for full traversal.
*
* <zltail> 保存着到达列表中最后一个节点的偏移量。
*
* 这个偏移量使得对表尾的 pop 操作可以在无须遍历整个列表的情况下进行。
*
* <zllen> is the number of entries.When this value is larger than 2**16-2,
* we