链表
链表提供了高效的节点重排能力,以及顺序性的节点访问方式,且可以通过增删节点来灵活地调整链表的长度;
列表键的底层实现之一就是链表;当有一个列表键包含了数量较多的元素,或列表中包含的元素都是比较长的字符串时,Redis就会使用链表作为列表键的底层实现;
除列表键之外,发布与订阅、慢查询、监视器等功能也用到了链表,Redis服务器本身还用链表来保存多个客户端的状态信息,以及使用链表来构建客户端输出缓冲区;
链表和链表节点的实现
每个链表节点使用adlist.h/listNode结构来表示:
链表的使用adlist.h/list结构来表示:
其中:
- dup函数用于复制链表节点所保存的值;
- free函数用于释放链表节点所保存的值;
- match函数用于对比链表节点所保存的值与另一个输入值是否相等;
其结构如图:
Redis的链表实现特性:
- 双端:链表节点有 前驱、后继指针,获取前驱、后继节点的时间复杂度为O(1);
- 链表实现带有表头、表尾指针:可以O(1)的时间复杂度获取表头、表尾节点;
- 无环:表头节点的前驱指针、表尾节点的后继指针均指向NULL;
- 带链表长度计数器:通过len属性可以O(1)的时间复杂度获知链表节点个数;
- 多态:链表节点使用void*指针来保存节点值,可用于保存不同类型的数据值;