1.Redis的链表是什么?
我们学数据结构的时候,学完数组应该就会开始链表的学习,链表的思想学习之后才会往下学二叉树这些复杂的数据结构.但已知Redis是用C语言实现的,C语言的API中没有现成的链表结构,需要我们自己写一下.
-
链表在Redis的应用场景
1)当列表键包含了较多的元素/列表中的元素都得比较长的字符串时,Redis使用链表作为列表键的底层实现.
2)发布与订阅\慢查询\监视器
3)Redis服务器用链表保存多个客户端的状态信息,使用链表来构建客户端输出缓冲区output buffer -
链表的优点
在学数据结构和日常的算法场景设计使用中,我们都有这样的体会,链表的查找慢需要遍历实现,但是插入和删除迅速,不需要移动其他位置的元素,只要改变前驱/后驱节点的pre/next指针方向即可快速实现,对于需要频繁的删除/插入操作的场景十分适用.
2.如何实现Redis的链表节点和链表
- 节点实现
typedef struct listNode{
struct listNode *prev;//前置节点
struct listNode *next;//后置节点
void *value;//节点的值
}
可以看出Redis使用的是双向链表,每个节点包括前驱和后驱两个指针,更加高效.
- 链表实现
typedef struct list{
listNode *head;//表头节点
listNode *tail;//表尾的节点
unsigned long len;//链表中的节点数量
void *(*dup)(void *ptr);//节点复制函数
void (*free)(void *ptr);//节点值释放函数
int (*match)(void *ptr,void *key);//节点值对比函数
}
3.Redis链表的特性有哪些?
- 1)双端:每个节点都包含prev和next指针,获取已知节点node的前置和后置节点的复杂度为O(1)
- 2)无环:整个表的头节点prev指针指向NULL空节点,尾节点的next指针也指向NULL,对链表进行正向/反向遍历的时候不会形成环造成死循环,遍历一遍就会到达条件跳出
- 3)有表头指针和表尾指针:通过表的head和tail指针,能在O(1)复杂度内找到表的表头和表尾
- 4)带有表长度计数器:通过dup()函数获取表中的节点数量,复杂度O(1)
- 5)多态;节点中使用void *指针保存节点值,可以使用链表的函数对节点值进行设置,保存不同的值
- Redis链表节点的相关API