redis基础数据结构(三) 双链表adlist

redis的adlist是一个标准双链表,源码在adlist.h和adlist.c中,adlist.h中提供的结构定义和宏如下
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);
    unsigned long len;
} list;


/* Functions implemented as macros */
#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)

使用时和内核链表的思想是一样的,将listNode嵌入其他结构中。list是头,除了指向头和尾的指针,还有释放、复制等一系列方法的指针,listnode是节点,listIter是迭代器。

adlist.c中提供的api:

listCreate:创建一个adlist

listEmpty:释放list的所有节点,但保留adlist头

listRelease:彻底销毁一个adlist

listAddNodeHead:插入一个节点到list头

listAddNodetail:插入一个节点到链表尾

listInsertNode:插入一个节点到某个节点前面或者后面

listDelNode:删除一个节点

listGetIterator:创建一个迭代器

listReleaseIterator:销毁迭代器

listRewind:重置一个迭代器从头开始

listRewindTail:重置一个迭代器从尾开始

listNext:传入迭代器获取下一个节点

listDup:复制一个adlist

listSearechKey:在adlist中查找节点

listIndex:返回第index个节点,index可以是负数,表示从尾开始

listRotate:将adlist的尾节点移动到头

listJoin:将一个adlist连接到另一个adlist后面,注意被连接的adlist头还在,调用者考虑是否要释放内存

展开阅读全文

没有更多推荐了,返回首页