鏈表提供了高效的節點重排能力, 以及順序性的節點存取方式, 並且可以通過增刪節點來靈活地調整鏈表的長度。
作爲一種常用數據結構, 鏈表內建在很多高階的程式語言裏面, 因爲Redis使用的C語言並沒有內建這種數據結構, 所以Redis構建了自己的鏈表實現。
鏈表在Redis中的應用非常廣泛, 比如列表鍵的底層實現之一就是鏈表。 當一個列表鍵包含了數量比較多的元素, 又或者列表中包含的元素都是比較長的字串時, Redis就會使用鏈表作爲列表鍵的底層實現。
每個鏈表節點使用一個adlist.h/listNode結構來表示:
typedef struct listNode {
//
前置節點
struct listNode * prev;
//
後置節點
struct listNode * next;
//
節點的值
void * value;
}listNode;
多個listNode可以通過prev和next指針組成雙端鏈表,如下圖所示:
雖然僅僅使用多個listNode結構就可以組成鏈表, 但使用adlist.h/list來持
有鏈表的話, 操作起來會更方便:
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;
list結構爲鏈表提供了表頭指針head、 表尾指針tail, 以及鏈表長度計數器len, 而dup、 free和match成員則是用於實現多型鏈表所需的型別特定函數: