一、概述
adlist是redis自己实现的一种列表类型的数据结构,它采用了双向表的方式来实现。具体结构如图1:
图1、adlist的内存结构示意图
adilist模块主要使用到的文件为:
https://github.com/yubing-1987/redis-3.2-comment/blob/master/src/adlist.c
https://github.com/yubing-1987/redis-3.2-comment/blob/master/src/adlist.h
二、主要的结构体
1、列表结构体-----list
/*
*列表的结构体
*/
typedef struct list {
//表头
listNode *head;
//表尾
listNode *tail;
//复制回调函数指针
void *(*dup)(void *ptr);
//清空回调函数指针
void (*free)(void *ptr);
//比对回调函数指针
int (*match)(void *ptr, void *key);
//节点个数
unsigned long len;
} list;
这个结构体中主要定义的是list的结构,在图1中就是list、head、tail展示的部分。
同时这里还定义了dup,free,match三个函数指针,
dup------在进行list的复制的时候,对于每一个节点会尝试调用这个函数进行深拷贝,代码为:
//遍历全部的元素,并进行复制
while((node = listNext(iter)) != NULL) {
void *value;
//如果设置了复制回调函数指针,就调用回调函数来获取节点值
//否则直接把源节点的值复制过来
if (copy->dup) {
//调用复制回调函数
//这是深拷贝
value = copy->dup(node->value);
if (value == NULL) {
//复制回调函数调用失败
//释放新的列表
listRelease(copy);
//释放迭代器
listReleaseIterator(iter);
return NULL;
}
} else
//直接复制,这是浅拷贝
value = node->value;
//把复制得到的节点添加到新列表的末尾
if (listAddNodeTail(copy, value) == NULL) {
//添加失败,释放资源,并返回[NULL]
listRelease(copy);
listReleaseIterator(iter);
return NULL;
}
}
free----在销毁list的时候会对列表中的每一个节点调用这个函数,进行深度的销毁工作,代码为:
//获取表头节点
current = list->head;
//获取列表节点个数
len = list->len;
//遍历列表的每一个节点
while(len--) {
//保存下一个节点
next = current->next;
//如果设置了清空的回调函数,就调用清空回调函数
if (list->free) list->free(current->value);
//释放节点内存
zfree(current);
//指向下一个节点
current = next;
}
match----在对节点中的值进行比较的时候回尝试调用这个函数,进行深度的比较,函数返回非0表示是一致的,返回0表示是不一致的。
2、列表节点的结构体----listNode
/*
* 列表节点结构体
* 描述了列表中每一个节点的内容
*/
typedef struct listNode {
//上一个节点的指针
struct listNode *prev;
//下一个节点的指针
struct listNode *next;
//节点值的指针
void *value;
} listNode;
这个结构体中定义的内容和图1中的Node向对应,prev指向上一个节点,如果上一个节点不存在就指向NULL,next指向下一个节点,如果下一个节点不存在就指向NULL,value存放实际数据的指针。
3、列表迭代器的结构体----listIter
/*
* 列表迭代器的结构体
*/
typedef struct listIter {
//下一个节点的指针
listNode *next;
//迭代器指向
int direction;
} listIter;
迭代器实际标记了下一个节点的指针,并且标记了迭代的方向,包括:
/*迭代器方向*/
#define AL_START_HEAD 0 //从头指向为
#define AL_START_TAIL 1 //从尾指向头
三、主要函数
listCreate 创建空列表
listRelease 销毁列表并释放内存
listAddNodeHead 在列表的头部添加一个节点
listAddNodeTail 在列表的尾部添加一个节点
listInsertNode 在列表中插入节点
listDelNode 删除列表中的节点
listGetIterator 获取列表的迭代器
listNext 获取迭代器指向的节点,并把迭代器指向下一个节点
listReleaseIterator 销毁迭代器,并释放内存
listDup 复制列表
listSearchKey 在列表中查找指定的节点
listIndex 在列表中查找指定位置的节点
listRewind 获取指向列表表头的迭代器
listRewindTail 获取指向列表表尾的迭代器