Reids 中的链表结构
原文链接:https://www.changxuan.top/?p=1117
链表,作为数据结构中的常客想必大家已经十分熟悉,在 Java 中也有许多类型的内置链表。Redis 使用C语言实现了自己的链表结构。
介绍
首先,在 Redis 中的链表与我们平常做算法题时用到的简单链表不太相同。具体来说,就是 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);
}list;
通过链表结构体包装之后,让我有一些面向对象的感觉。其结构体内字段的意义参考注释也一目了然。所以,总结一下 Redis 链表的特性如下:
双端链表,访问一个节点的前后节点更快。 线性无环,当前后指针都为 NULL 时,则链表为空。 记录头尾指针,可以方便的从前向后或从后向查找。 记录链表长度,还是考虑性能,获取长度时间复杂度为O(1)。 多态,使用 void*
来保存节点值,可以方便存取各种类型的值。
部分 API
函数 | 作用 |
---|---|
listSetDupMethod | 将给定的函数设置为链表的节点值复制函数 |
listFirst | 返回链表的头节点 |
listLast | 返回链表的尾节点 |
listLength | 返回链表的长度 |
listPrevNode | 返回给定节点的前置节点 |
listNextNode | 返回给定节点的后置节点 |
listDelNode | 从链表中删除给定节点 |
... ... | ... ... |