Redis之快速链表(quicklist)

什么是快速链表

快速链表是Redis3.2之后引入的一种数据类型, 该结构它是由链表和压缩链表结合起来的一种结构, 即是一个双向链表, 并且链表中的每一个节点是一个压缩链表. 这样的设计能在时间效率和空间效率上实现较好的折中
在3.2之前列表是用, 双向链表或者压缩链表来实现的, 到了3.2之后, 列表底层就全用快速链表来实现了

快速链表结构

typedef struct quicklist {
    
    
    //指向头部(最左边)quicklist节点的指针
    quicklistNode *head;

    //指向尾部(最右边)quicklist节点的指针
    quicklistNode *tail;

    //ziplist中的entry节点计数器
    unsigned long count;       

    //quicklist的quicklistNode节点计数器
    unsigned int len;           

    //保存ziplist的大小,配置文件设定,占16bits
    int fill : 16;              

    //保存压缩程度值,配置文件设定,占16bits,0表示不压缩
    unsigned int compress : 16; // compress;0=off 
} quicklist;
typedef struct quicklistNode {
    
    
    struct quicklistNode *prev; //上一个node节点
    struct quicklistNode *next; //下一个node
    unsigned char *zl;            //保存的数据 压缩前ziplist 压缩后压缩的数据
    unsigned int sz;             /* ziplist size in bytes */
    unsigned int count : 16;     /* count of items in ziplist */
    unsigned int encoding : 2;   /* RAW==1 or LZF==2 */
    unsigned int container : 2;  /* NONE==1 or ZIPLIST==2 */
    unsigned int recompress : 1; /* was this node previous compressed? */
    unsigned int attempted_compress : 1; /* node can't compress; too small */
    unsigned int extra : 10; /* more bits to steal for future usage */
} quicklistNode;
}
  • prev: 指向链表前一个节点的指针。
  • next: 指向链表后一个节点的指针。
  • zl: 数据指针。如果当前节点的数据没有压缩,那么它指向一个ziplist结构;否则,它指向一个quicklistLZF结构。
  • sz: 表示zl指向的ziplist的总大小(包括zlbytes, zltail, zllen, zlend和各个数据项)。需要注意的是:如果ziplist被压缩了,那么这个sz的值仍然是压缩前的ziplist大小。
  • count: 表示ziplist里面包含的数据项个数。这个字段只有16bit
  • encoding: 表示ziplist是否压缩了(以及用了哪个压缩算法)。目前只有两种取值:2表示被压缩了(而且用的是LZF压缩算法),1表示没有压缩。
  • container: 是一个预留字段。本来设计是用来表明一个quicklist节点下面是直接存数据,还是使用ziplist存数据,或者用其它的结构来存数据(用作一个数据容器,所以叫container)。但是,在目前的实现中,这个值是一个固定的值2,表示使用ziplist作为数据容器。
  • recompress: 当我们使用类似lindex这样的命令查看了某一项本来压缩的数据时,需要把数据暂时解压,这时就设置recompress=1做一个标记,等有机会再把数据重新压缩。
  • attempted_compress: 这个值只对Redis的自动化测试程序有用。我们不用管它。
  • extra: 其它扩展字段。目前Redis的实现里也没用上。
    在这里插入图片描述
    从代码可以看出,quicklist实际上是ziplistlinkedlist的混合体,它将linkedlist按段进行切分,每一段使用ziplist进行紧凑存储,多个ziplist之间使用双向指针进行串接

下面是一个详细一点的理解图
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_53804791/article/details/121382339