redis源码阅读(2)---- adlist分析

一、概述

       adlist是redis自己实现的一种列表类型的数据结构,它采用了双向表的方式来实现。具体结构如图1:        

redis源码阅读(2)---- adlist分析_第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            获取指向列表表尾的迭代器

你可能感兴趣的:(redis,阅读)