快速列表quicklist是一个由压缩列表ziplist组成的双端链表,链表中每个结点都有一个ziplist,每个ziplist有多个entry,主要用于列表键的底层实现,替换了原有的双端链表adlist。
1. 定义
快速列表结点
结点进行压缩后,zl指向的是压缩后的LZF结构体,其中compressd中存储的压缩的内容
1 | typedef struct quicklistNode { |
- 快速列表LZF算法压缩ziplist
1 | typedef struct quicklistLZF { |
快速列表
head,tail:头尾结点
count:所有结点中ziplist中entry的总和
len:quicklistNode结点个数
fill:16bit,表示ziplist的大小限制【redis.conf中list-max-ziplist-size可配置】
负数表示每个快速列表结点中ziplist的大小限制
-1: 4KB、-2: 8KB(默认) 、-3: 16KB 、-4: 32KB -5: 64KB
正数表示每个快速列表结点中ziplist包含最多entry的个数,最大2^15
compress:16bit,表示列表两端不需要压缩的结点数【redis.conf中list-compress-depth可配置】
- 0表示不压缩
- 1表示列表前后两端各有1个结点不压缩
- 2表示列表前后两端各有2个结点不压缩
- ……
1 | typedef struct quicklist { |
- 快速列表迭代器
1 | typedef struct quicklistIter { |
- 快速列表结点entry
1 | typedef struct quicklistEntry { |
2. 源码剖析
entry插入
由于每个结点中的ziplist有大小限制,所以在node结点满的情况下,会做特殊处理
- 插入结点未满则插入结点的ziplist中
- 插入结点已满,则根据插入的位置判断前驱或后继是否已满,若未满则插入前驱或后继的ziplist
- 插入结点已满,前驱和后继也已满,则创建新的结点,插入到新结点的ziplist,并将该结点插入到快速列表中
1 | REDIS_STATIC void _quicklistInsert(quicklist *quicklist, quicklistEntry *entry, |
entry删除
根据范围进行删除,若结点中ziplist全部删除,则需要删除该结点
1 | int quicklistDelRange(quicklist *quicklist, const long start, |