一、概述
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; } }
//获取表头节点 current = list->head; //获取列表节点个数 len = list->len; //遍历列表的每一个节点 while(len--) { //保存下一个节点 next = current->next; //如果设置了清空的回调函数,就调用清空回调函数 if (list->free) list->free(current->value); //释放节点内存 zfree(current); //指向下一个节点 current = next; }
2、列表节点的结构体----listNode
/* * 列表节点结构体 * 描述了列表中每一个节点的内容 */ typedef struct listNode { //上一个节点的指针 struct listNode *prev; //下一个节点的指针 struct listNode *next; //节点值的指针 void *value; } listNode;
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 获取指向列表表尾的迭代器