redis基础数据结构——QuickList
ZipList的问题是需要分配一块连续的完整的内存,内存占用较多时会导致效率低下。
为了解决ziplist的问题,我们需要限制每个ziplist的长度与entry的数量。
因此我们引入了QuickList,QuickList是一种基于双端链表的数据结构,他将ziplist(后来用listpack)作为node的val
QuickList的基础数据结构
typedef struct quicklist { quicklistNode *head; quicklistNode *tail; unsigned long count; /*这里是所有的listpack的entry的数量,老版本是所有的ziplist的数量*/ unsigned long len; /* listpack的数量,老版本是ziplist的数量 */ signed int fill : QL_FILL_BITS; /* 控制大小,为正数的时候表示最多能有n个entry,为负数的时候表示最多占用x kb内存,默认为-2 */ unsigned int compress : QL_COMP_BITS; /* 首尾节点不压缩的节点数量,默认情况为0 */ unsigned int bookmark_count: QL_BM_BITS; quicklistBookmark bookmarks[]; } quicklist;
这里的fill控制entry的大小/ziplist的容量:在Redis的conf文件中通过list-max-ziplist-size可以限制
QuickListNode的数据结构
typedef struct quicklistNode { struct quicklistNode *prev; struct quicklistNode *next; unsigned char *entry; /* 指针,指向listpack/ziplist的 */ size_t sz; /* 当前节点的entry的大小 */ unsigned int count : 16; /* listpack内的entry个数 */ unsigned int encoding : 2; /* RAW==1 or LZF==2 */ unsigned int container : 2; /* PLAIN==1 or PACKED==2 */ unsigned int recompress : 1; /* was this node previous compressed? */ unsigned int attempted_compress : 1; /* node can't compress; too small */ unsigned int dont_compress : 1; /* prevent compression of entry that will be used later */ unsigned int extra : 9; /* 预留字段,无实意 */ } quicklistNode;