ziplist本质上就是字符串数组
当存储元素数量<UINT16_MAX时,可以直接读取长度
当存储元素数量>=UINT16_MAX时,需要遍历整个ziplist才能获取长度
采用了不同的编码来对数字,字符串存储进行了压缩
- 结构
<总字节数(4字节)><最后一个元素的偏移量(从头开始算)(4字节)><总元素个数(2字节)><数据(不定字节)>…<0xFF结尾标记(1字节)> - 数据的结构
- 头
- 前一个数据的编码类型和长度
- 当长度小于0xFE时,是一个字节
- 当长度大于等于0xFE时,是5个字节(第一个字节+4个字节的长度信息)
- 当前数据的编码类型和长度
第一个字节的前两位- 字符串
- 00??????
数据头总共占用一个字节
后六位表示字符串长度 - 01??????|????????
数据头总共占用两个字节
后14位表示字符串长度 - 10______|????????|????????|????????|????????
数据头总共占用5个字节
后4个字节表示字符串长度
- 00??????
- 数字
- 11000000
表示int16_t
后面两个字节为具体数据 - 11010000
表示int32_t
后面4个字节为具体数据 - 11100000
表示int64_t
后面8个字节为具体数据 - 11110000
表示int24_t
后面3个字节为具体数据 - 11111110
表示int8_t
后面1个字节为具体数据 - 11110001-11111101
直接表示0-12的值
后面没有数据
值直接就在当前字节中
其中
11110001 0
11110010 1
…
11111101 12
就是字节后4位的值直接转化为整数
然后-1所得的值
结尾不是1110是因为1110为int8_t
结尾不是1111是因为1111为ziplist结尾标记
- 11000000
- 字符串
- 前一个数据的编码类型和长度
- 数据
根据数据长度定义的连续字符串
- 头
相关文件
数据结构
1 | typedef struct zlentry { // ziplist的单个entry元素结构体 |
主要宏
1 |
|
函数分析
unsigned int zipIntSize(unsigned char encoding);
功能
根据编码获取编码占用字节数
源码
1 | /* Return bytes needed to store integer encoded by 'encoding' */ |
unsigned int zipEncodeLength(unsigned char *p, unsigned char encoding, unsigned int rawlen);
功能
设置编码,长度到ziplist中
源码
1 | /* Encode the length 'rawlen' writing it in 'p'. If p is NULL it just returns |
unsigned int zipPrevEncodeLength(unsigned char *p, unsigned int len);
功能
设置前一个元素的长度到数据中
当p为NULL时直接返回需要存储该长度需要的字节数
源码
1 | /* Encode the length of the previous entry and write it to "p". Return the |
void zipPrevEncodeLengthForceLarge(unsigned char *p, unsigned int len);
功能
强制使用5个字节的长度标记记录前一个字节的长度信息
源码
1 | /* Encode the length of the previous entry and write it to "p". This only |
int zipPrevLenByteDiff(unsigned char *p, unsigned int len);
功能
获取到要存储len长度的数据需要的字节数和前一个元素当前存储长度所用的字节数的差值
源码
1 | /* Return the difference in number of bytes needed to store the length of the |
unsigned int zipRawEntryLength(unsigned char *p);
功能
获取到元素的整体长度
前一个元素的长度+当前元素的长度+当前元素的数据长度
源码
1 | /* Return the total number of bytes used by the entry pointed to by 'p'. */ |
int zipTryEncoding(unsigned char *entry, unsigned int entrylen, long long *v, unsigned char *encoding);
功能
将字符串转化为数字,并将可以存储该数字的编码格式返回
源码
1 | /* Check if string pointed to by 'entry' can be encoded as an integer. |
void zipSaveInteger(unsigned char *p, int64_t value, unsigned char encoding);
功能
根据编码格式将值存储在字符数组中
源码
1 | /* Store integer 'value' at 'p', encoded as 'encoding' */ |
int64_t zipLoadInteger(unsigned char *p, unsigned char encoding);
功能
根据编码读取数字数据
源码
1 | /* Read integer encoded as 'encoding' from 'p' */ |
void zipEntry(unsigned char *p, zlentry *e);
功能
读取一个完整的zlentry
源码
1 | /* Return a struct with all information about an entry. */ |
unsigned char *ziplistNew(void);
功能
创建一个新的ziplist
源码
1 | /* Create a new empty ziplist. */ |
unsigned char *ziplistResize(unsigned char *zl, unsigned int len);
功能
ziplist重新分配内存大小
源码
1 | /* Resize the ziplist. */ |
unsigned char *__ziplistCascadeUpdate(unsigned char *zl, unsigned char *p);
功能
插入新元素后,维护后续元素的前一个元素的尺寸接口
源码
1 | /* When an entry is inserted, we need to set the prevlen field of the next |
unsigned char *__ziplistDelete(unsigned char *zl, unsigned char *p, unsigned int num);
功能
从p开始删除num个元素
源码
1 | /* Delete "num" entries, starting at "p". Returns pointer to the ziplist. */ |
unsigned char *__ziplistInsert(unsigned char *zl, unsigned char *p, unsigned char *s, unsigned int slen);
功能
在p的位置插入元素
源码
1 | /* Insert item at "p". */ |
unsigned char *ziplistMerge(unsigned char **first, unsigned char **second);
功能
合并两个ziplist,返回新的ziplist
源码
1 | /* Merge ziplists 'first' and 'second' by appending 'second' to 'first'. |
unsigned char *ziplistPush(unsigned char *zl, unsigned char *s, unsigned int slen, int where);
功能
向ziplist添加数据
where表示在前面或者后面添加数据
源码
1 |
|
unsigned char *ziplistIndex(unsigned char *zl, int index);
功能
根据索引获取元素
源码
1 | /* Returns an offset to use for iterating with ziplistNext. When the given |
unsigned char *ziplistNext(unsigned char *zl, unsigned char *p);
功能
获取ziplist的下一个元素
源码
1 | /* Return pointer to next entry in ziplist. |
unsigned char *ziplistPrev(unsigned char *zl, unsigned char *p);
功能
获取ziplist的前一个元素
源码
1 | /* Return pointer to previous entry in ziplist. */ |
unsigned int ziplistGet(unsigned char *p, unsigned char **sstr, unsigned int *slen, long long *sval);
功能
p为ziplist的一个entry的起始位置
获取这个p指向的entry的字符串或这值
源码
1 | /* Get entry pointed to by 'p' and store in either '*sstr' or 'sval' depending |
unsigned char *ziplistInsert(unsigned char *zl, unsigned char *p, unsigned char *s, unsigned int slen);
功能
在ziplist的p位置插入新的元素
源码
1 | /* Insert an entry at "p". */ |
unsigned char *ziplistDelete(unsigned char *zl, unsigned char **p)
功能
删除ziplist元素,返回新的ziplist
源码
1 | /* Delete a single entry from the ziplist, pointed to by *p. |
unsigned char *ziplistDeleteRange(unsigned char *zl, int index, unsigned int num);
功能
从index开始连续删除num个元素
源码
1 | /* Delete a range of entries from the ziplist. */ |
unsigned int ziplistCompare(unsigned char *p, unsigned char *sstr, unsigned int slen);
功能
判断传入的数据是否与p对应的元素的值相同
源码
1 | /* Compare entry pointer to by 'p' with 'sstr' of length 'slen'. */ |
unsigned char *ziplistFind(unsigned char *p, unsigned char *vstr, unsigned int vlen, unsigned int skip);
功能
查找指定元素
skip:需要跳过的元素的个数
源码
1 | /* Find pointer to the entry equal to the specified entry. Skip 'skip' entries |
unsigned int ziplistLen(unsigned char *zl);
功能
获取ziplist的长度
源码
1 | /* Return length of ziplist. */ |
size_t ziplistBlobLen(unsigned char *zl);
功能
获取ziplist的总占用字节数
源码
1 | /* Return ziplist blob size in bytes. */ |