REDIS中List是如何实现的?
redis中的list本质就是链表。
链表是由一个一个的节点组成的,这个没什么疑问吧?节点就是node,然后一个node和一个node中间串联起来就是链表。
我们先看下node的C语言结构体,如下:
struct listNode { // 指向前一个节点的指针 listNode * prev; // 指向后一个节点的指针 listNode * next; // 本节点的值 void * value; } listNode;
然后,这些node的struct串串在了一起组成了一个list,如下所示:
struct list { // 队列第一个节点的指针 listNode * head; // 队列最后一个节点的指针 listNode * tail; // 队列中元素的数量 unsigned long len; // 节点值复制函数 void *(*dup) ( void * ptr ); // 释放一个节点 void (*free) ( void * ptr ); // 两个节点对比 void (*match) ( void * ptr, void * key ); } list;
所以实际上,当我们通过llen来获取list长度的时候,这是一个时间复杂度为O( 1 )的调用。
但实际上,redis为了压榨内存性能极限,并不是一直使用了单纯的链表,而是还采用了ziplist,也就是压缩表。ziplist是一个极为节省内存的存储结构,当数据量不大的时候将会list会采用ziplist而不是linklist来存储数据。
新版本的redis,更加压榨了内存极致。除了ziplist外,还引入了quicklist。其中quicklist由一个又一个的quicklistNode组成,每个quicklistNode又由一堆ziplist node组成,整体数据结构如下: