链表作为一种常见的数据结构,一般都会内置在很多高级语言中。由于Redis使用的是C语言并没有内置这种数据结构,所以Redis构建了自己的链表实现。
链表在Redis中应用广泛,比如列表建的底层实现之一就是链表。当一个列表键包含了数量比较多的元素,又或者列表中包含的元素都是比较长的字符串,列表会使用链表作为列表键的底层实现。
除了链表键之外,发布于订阅,慢查询,监视器等功能也用到了链表,redis服务器本身还使用链表来保存多个客户端的状态信息,以及使用链表来构建客户端输出缓冲区。
在redis源码中,每一个链表节点使用adlist.h/listNode结构来表示:
- /* Node, List, and Iterator are the only data structures used currently. */
-
- typedef struct listNode {
- struct listNode *prev;
- struct listNode *next;
- void *value;
- } listNode;
多个listNode可以通过prev和next指针组成双端链表

虽然使用多个listNode就可以组成链表,使用在Redis源码中使用adlist.h/list来持有链表,操作起来回更加方便。
- typedef struct list {
- //表头节点
- listNode *head;
- //表尾节点
- listNode *tail;
- //节点复制函数
- void *(*dup)(void *ptr);
- //节点释放函数
- void (*free)(void *ptr);
- //节点值对比函数
- int (*match)(void *ptr, void *key);
- //链表所包含的节点数量
- unsigned long len;
- } list;
list结构为链表提供了表头指针head,表尾指针tail,以及链表计数器len,而dup,free和match成员则是用实现多态链表所需的类型特定函数。
redis链表特性:

