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

一、概述

       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;
        }
    }

        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            获取指向列表表尾的迭代器

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值