因为c语言没有链表,所以写了结构体来封装一些链表操作的接口。
数据结构定义
listNode存储了先后结点和为了通用性,数据存储为void*类型,方便拓展,通用性强。
typedef struct listNode {
struct listNode *prev;
struct listNode *next;
void *value;
} listNode;
迭代器,方向表示正序or逆序,然后会存储初始节点。
typedef struct listIter {
listNode *next;
int direction;
} listIter;
list,放了一部分指针函数,方便定制,通用性更强。
list存储了头尾结点,复制函数指针,释放函数指针,匹配keyde指针和表示长度的unsigned long类型的len字段。
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;
宏定义下的函数
其实也是直接访问struct里面的数据,但是c不存在private/public概念,封装一层宏可以让外部不需要直到内部的数据细节而直接获取到需要的数据。
#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 listGetFreeMethod(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 listRotateTailToHead(list *list); | 将尾结点移到头结点 | |
void listRotateHeadToTail(list *list); | 将头结点移到尾结点 | |
void listJoin(list *l, list *o); | 合并到l,清空o,但o还是有效的list | |
void listInitNode(listNode *node, void *value); | ||
void listLinkNodeHead(list *list, listNode *node); | 添加一个已经被分配到list的结点到头部 | |
void listUnlinkNode(list *list, listNode *node); | 移除特定结点,但不free |
redis链表整体数据
如图所示
以上,就是adlist的主要内容,其余的源码都很简单,不赘述