Redis源码学习--双向链表adlist

双向链表

定义

链表结点

链表结点中保存两个指针,分别指向前后,还有一个void *指针指向保存的数据

typedef struct listNode {
    struct listNode *prev;
    struct listNode *next;
    void *value;
} listNode;

链表

链表,包含两个链表节点指针,一个指向head,一个指向tail
其中dup函数指针指向两个链表拷贝时对链表节点value的拷贝方法。
match为寻找链表中和key相同的value时的比较方法。

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;

链表迭代器

还有一个链表迭代器,在函数中访问,遍历链表都是通过迭代器完成。
direction为标志为前向迭代器还是反向迭代器。

typedef struct listIter {
    listNode *next;
    int direction;
} listIter;
#define AL_START_HEAD 0//前向
#define AL_START_TAIL 1//反向

通过定义宏来完成链表中函数指针的赋值以及或许一些信息

#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 listEmpty(list *list);

删除链表
清空,将本身也释放

void listRelease(list *list)
{
    listEmpty(list);
    zfree(list);
}

从头添加节点

list *listAddNodeHead(list *list, void *value);

从尾添加节点

list *listAddNodeTail(list *list, void *value);

插入节点
after表示在其给定节点的前面插入还是后面插入

list *listInsertNode(list *list, listNode *old_node, void *value, int after);

获取前向迭代器

void listRewind(list *list, listIter *li) {//正向
    li->next = list->head;
    li->direction = AL_START_HEAD;
}

函数内部通过迭代器遍历链表

listNode *listNext(listIter *iter)
{
    listNode *current = iter->next;

    if (current != NULL) {
        if (iter->direction == AL_START_HEAD)
            iter->next = current->next;
        else
            iter->next = current->prev;
    }
    return current;
}

通过索引访问元素,其中index为0表示head,-1表示tail

listNode *listIndex(list *list, long index) {
    listNode *n;

    if (index < 0) {
        index = (-index)-1;
        n = list->tail;
        while(index-- && n) n = n->prev;
    } else {
        n = list->head;
        while(index-- && n) n = n->next;
    }
    return n;
}

根据key值查找

listNode *listSearchKey(list *list, void *key)
{
    listIter iter;
    listNode *node;

    listRewind(list, &iter);
    while((node = listNext(&iter)) != NULL) {
        if (list->match) {
            if (list->match(node->value, key)) {
                return node;
            }
        } else {
            if (key == node->value) {
                return node;
            }
        }
    }
    return NULL;
}

你可能感兴趣的:(Redis)