Redis源码详解5:列表
Redis支持5种基本数据结构
- string
- list
- hash
- set
- zset
由于经过了大量的测试和商业使用,这5种数据结构被看作是十分经典的C语言实现,性能优良,可以为其他软件的开发提供借鉴。
Redis中使用了多种列表结构,有adlist,ziplist,quicklist和skiplist,各有各的特点。先来看一个简单的列表实现adlist,因为结构比较简单,在这里先做介绍。列表数据结构的源代码在adlist.h和adlist.c。先来看头文件adlist.h,首先定义了3个结构体
// 双向链表节点
typedef struct listNode {
// 前一节点
struct listNode *prev;
// 后一节点
struct listNode *next;
// 节点储存的值
void *value;
} listNode;
// 链表迭代器
typedef struct listIter {
// 下一节点
listNode *next;
// 迭代方向
int direction;
} listIter;
// 链表数据结构
typedef struct list {
// 头尾节点
listNode *head;
listNode *tail;
// 复制函数指针
void *(*dup)(void *ptr);
// 释放函数指针
void (*free)(void *ptr);
// 匹配函数指针
int (*match)(void *ptr, void *key);
// len链表长度
unsigned long len;
} list;
可以看出Redis的列表数据结构是用双向链表实现的。
然后是一组宏定义的函数
// 宏定义的函数
#define listLength(l) ((l)->len)
#define listFirst(l) ((l)->head)
#define listLast(l) ((l)->tail)
#define listPrevNode(n) ((n)->prev)
#define listNextNode(n) ((n)->next)
#define listNodeValue(n) ((n)->value)
#define listSetDupMethod(l,m) ((l)->dup = (m))
#define listSetFreeMethod(l,m) ((l)->free = (m))
#define listSetMatchMethod(l,m) ((l)->match = (m))
#define listGetDupMethod(l) ((l)->dup)
#define listGetFree(l) ((l)->free)
#define listGetMatchMethod(l) ((l)->match)
接下来是一组普通函数声明
list *listCreate(void);
void listRelease(list *list);
void listEmpty(list *list);
list *listAddNodeHead(list *list, void *value);
list *listAddNodeTail(list *list, void *value);
list *listInsertNode(list *list, listNode *old_node, void *value, int after);
void listDelNode(list *list, listNode *node);
listIter *listGetIterator(list *list, int direction);
listNode *listNext(listIter *iter);
void listReleaseIterator(listIter *iter);
list *listDup(list *orig);
listNode *listSearchKey(list *list, void *key);
listNode *listIndex(list *list, long index);
void listRewind(list *list, listIter *li);
void listRewindTail(list *list, listIter *li);
void listRotate(list *list);
void listJoin(list *l, list *o);
最后是迭代方向的宏定义
// 从头部开始迭代
#define AL_START_HEAD 0
// 从尾部开始迭代
#define AL_START_TAIL 1