目录

1、ADList概述

2、链表和链表节点定义

3、链表迭代器

4、总结


1、ADList概述

       ADList(A generic doubly linked list)是 redis 自定义的一种双向链表,广泛运用于 redisClients 、 redisServer 、发布订阅、慢查询、监视器等(注:3.0及以前还会被运用于list结构中,在3.2以后被quicklist取代)。
       链表是最常用的数据结构之一了,对于其算法和ADT就不做赘述,不了解的同学可以google、百度或者参考《数据结构:C语言版》等书籍。

2、链表和链表节点定义

每个链表节点都是用一个listNode表示

typedef struct listNode {   // 双向节点struct listNode *prev;struct listNode *next;void *value;    // 空指针,可以被指向任何类型
} listNode;

在简单的链表定义中,只用节点结构就已经能够满足链表的需求了,但是 redis 通过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;
  • dup为节点复制函数
  • free为节点释放函数
  • match为节点比较函数

通过这样的定义,adlist有了以下优点:

  1. 双向:可以灵活的访问前置或者后置节点
  2. list头指针和尾指针:可以方便的获取头尾节点或者从头尾遍历查找
  3. len:使获取listO(N)变为O(1)
  4. 通过void实现多态:不同的实例化链表对象可以持有不同的值,其对应的3个操作函数也可以自定义,是不是有点interface的感觉!

3、链表迭代器

除了双向链表的定义外,redis 还定义了一个迭代器,用于遍历链表:

typedef struct listIter {   // 列表迭代器listNode *next;int direction;  // 迭代器遍历方向
} listIter;

其中direction用于标识迭代器的遍历方向:

#define AL_START_HEAD 0     // 从头遍历
#define AL_START_TAIL 1     // 从尾遍历

通过定义listIterredis 在需要遍历list时,不需要再复制各种tmp值,只需要调用listIter的遍历函数。 以listSearchKey为例:

listNode *listSearchKey(list *list, void *key)  // list查找key
{listIter iter;listNode *node;listRewind(list, &iter);    // 初始化迭代器while((node = listNext(&iter)) != NULL) {   // 迭代器遍历if (list->match) {  // 如果定义了match函数if (list->match(node->value, key)) {return node;}} else {    // 直接进行值比较if (key == node->value) {return node;}}}return NULL;
}

所有和遍历有关的行为都收敛到了listIter中,list就专注负责存储。

4、总结

  1. redis 的链表是双向无环的
  2. ADList持有链表的头尾节点指针,链表长度以及链表操作函数
  3. listNode的值为void,可以保存任意类型的值
  4. 通过实现不同的操作函数,ADlist可以保存各种不同类型的数据
  5. 迭代操作由专门的迭代器实现

其他一些api就不做深入解析了,ADList相关的定义都在adlist.hadlist.c文件中,如果感兴趣可以自行查看

redis源码剖析(2):基础数据结构ADLIST相关推荐

  1. redis源码剖析(3):基础数据结构dict

    目录 1.dict概述 2.字典的定义 3.哈希算法 4.字典的初始化及新增键值对 4.1 字典初始化 4.2 新增键值对 5.rehash(重新散列)操作 5.1 rehash操作方式 5.2 re ...

  2. 【Redis源码剖析】 - Redis内置数据结构之压缩列表ziplist

    在前面的一篇文章[Redis源码剖析] - Redis内置数据结构之双向链表中,我们介绍了Redis封装的一种"传统"双向链表list,分别使用prev.next指针来指向当前节点 ...

  3. 【Redis源码剖析】 - Redis持久化之RDB

    原创作品,转载请标明:http://blog.csdn.net/xiejingfa/article/details/51553370 Redis源码剖析系列文章汇总:传送门 Redis是一个高效的内存 ...

  4. redis源码剖析(十五)——客户端思维导图整理

    redis源码剖析(十五)--客户端执行逻辑结构整理 加载略慢

  5. Redis源码剖析和注释(十六)---- Redis输入输出的抽象(rio)

    Redis源码剖析和注释(十六)---- Redis输入输出的抽象(rio) . https://blog.csdn.net/men_wen/article/details/71131550 Redi ...

  6. 【Redis源码剖析】 - Redis IO操作之rio

    原创作品,转载请标明:http://blog.csdn.net/xiejingfa/article/details/51433696 Redis源码剖析系列文章汇总:传送门 Reids内部封装了一个I ...

  7. Redis源码剖析之GEO——Redis是如何高效检索地理位置的?

    Redis GEO 用做存储地理位置信息,并对存储的信息进行操作.通过geo相关的命令,可以很容易在redis中存储和使用经纬度坐标信息.Redis中提供的Geo命令有如下几个: geoadd:添加经 ...

  8. Redis源码剖析之内存淘汰策略(Evict)

    文章目录 何为Evict 如何Evict Redis中的Evict策略 源码剖析 LRU具体实现 LFU具体实现 LFU计数器增长 LFU计数器衰减 evict执行过程 evict何时执行 evict ...

  9. Redis源码分析:基础概念介绍与启动概述

    Redis源码分析 基于Redis-5.0.4版本,进行基础的源码分析,主要就是分析一些平常使用过程中的内容.仅作为相关内容的学习记录,有关Redis源码学习阅读比较广泛的便是<Redis设计与 ...

  10. redis源码剖析(7):基础数据结构quicklist

    目录 1.quicklist概述 2.quicklist源码分析 2.1 定义 2.2 push操作 2.3 节点压缩 3.总结 1.quicklist概述    quicklist是一个3.2版本之 ...

最新文章

  1. 今年端午节,想回家看看父母...
  2. [HAOI2008][BZOJ1042] 硬币购物
  3. ashx PHP文件 优劣,.NET_后缀为 ashx 与 axd 的文件区别浅析,唯一不同的地方是:axd扩展名 - phpStudy...
  4. linux 父子进程 资源_linux 父子进程 资源_实验4 Linux父子进程同步
  5. html分块时边距的设置,html – 文本节点后第一个块的边距(垂直空间)?
  6. PRML5-神经网络(1)
  7. Mail: JMail, System.Net.Mail, System.Web.Mail
  8. 【softmax分类】基于matlab梯度下降softmax回归minist数据分类【含Matlab源码 1645期】
  9. 242.有效的字母异位词
  10. 基于RV1126平台imx291分析 --- media部件注册 rkcif_mipi
  11. php支付接口要改动的参数,京东支付接口2.0PHP集成遇到的一些问题:所有参数必须是string!...
  12. 如何创建一个vue项目(详细步骤)
  13. iOS非常全的第三方库
  14. Docker安装ElasticSearch 版本7.6.2
  15. quickchm乱码问题
  16. 解决sqllite的'unable to open database file'错误
  17. phalapi可以依赖注入么_phalapi-进阶篇2(DI依赖注入和单例模式)
  18. XenDesktop7.15CU3 文件重定向Bug
  19. python音频转文字腾讯_使用Python三步完成文本到语音的转换
  20. 均值不等式中考_数学不等式解题技巧

热门文章

  1. 数字IC设计流程总结
  2. mysql周德伟课后答案_mysql数据库搜索
  3. Linux命令之umask
  4. JAVA学习笔记——JAVA基础语法(二)
  5. WordPress资源站点推荐
  6. 基础XML配置的AOP与基于注解实现的AOP详细对比
  7. NFS还是iSCSI?关于VMware vSphere的存储连接的选择题
  8. 毕业设计论文封面模板
  9. android开发框架_2019 年五大跨平台移动应用开发工具
  10. Ubuntu 安装 TPM-2.0 TSS 软件栈