Redis中的双端链表的数据结构与操作
发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,今天小编给大家分享的是Redis中的双端链表的数据结构与操作,很多人都不太了解,今天小编为了让大家更加了解Redis中的双端链表,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。adlis
千家信息网最后更新 2026年10月31日Redis中的双端链表的数据结构与操作
今天小编给大家分享的是Redis中的双端链表的数据结构与操作,很多人都不太了解,今天小编为了让大家更加了解Redis中的双端链表,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。
adlist作为Redis中的双端链表,在Redis中被广泛的应用到了很多地方,比如 slowlog的存储,主从复制中报错客户端,list数据结构的实现等,很多都与此相关,所以也是非常重要的一个数据结构。
一)、Redis中双端链表的数据结构
双端链表(以下代码定义在 src/adlist.h):
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;双端链表的节点(以下代码定义在 src/adlist.h):
typedef struct listNode { struct listNode *prev; //当前节点的上一个节点 struct listNode *next; //当前节点的下一个节点 void *value; //当前节点存储的值,可以任意类型} listNode;list 通过 head 和 tail两个指针分别指向链表的头尾两端,使得遍历链表可以从正反两个顺序进行遍历,而 listNode 的void *value,则可以保存任意数据,并可以通过dup,free,match来自定义如何处理listNode的值。
二、双端链表的简单操作
创建链表(以下代码定义在 src/adlist.c):
list *listCreate(void){ struct list *list; //初始化链表 //为链表分配内存 if ((list = zmalloc(sizeof(*list))) == NULL) return NULL; //为空链表设置初始值 list->head = list->tail = NULL; list->len = 0; list->dup = NULL; list->free = NULL; list->match = NULL; return list;}追加到链表结尾(以下代码定义在 src/adlist.c):
list *listAddNodeTail(list *list, void *value){ listNode *node; //初始化node节点 //为新的node节点分配内存 if ((node = zmalloc(sizeof(*node))) == NULL) return NULL; //为node节点设置值 node->value = value; if (list->len == 0) { //如果空链表则 将头尾指向 新节点 并后继前驱节点设置为NULL list->head = list->tail = node; node->prev = node->next = NULL; } else { //否则将节点的前驱节点设置为原来的尾部节点 node->prev = list->tail; //由于追加到尾部,后继节点为NULL node->next = NULL; //之前的尾部节点的后继节点设置为新增的节点 list->tail->next = node; //将列表的尾部节点指针指向新增的节点 list->tail = node; } //增加链表长度 list->len++; return list;}遍历链表:
常用的遍历链表有两种方式,一个是根据链表长度通过while循环去手动遍历,还有一种是用Redis双端链表提供的迭代器来遍历。
手动遍历(以下代码定义在 src/adlist.c 中的 内存释放函数):
void listRelease(list *list){ unsigned long len; //current表示当前遍历的游标指针,next表示下次遍历的游标指针(next作为临时变量用于保存下一个节点) listNode *current, *next; //将current指向头部节点 current = list->head; //计算长度(其实就是 listLength(list)) len = list->len; //通过长度递减的方式进行遍历,便利到长度为0的时候,遍历结束 while(len--) { //保存下次循环的节点指针 next = current->next; //释放掉当前节点,如果设置释放节点的回调函数,则执行用户自定义的函数 if (list->free) list->free(current->value); zfree(current); //将游标指向下个节点 current = next; } zfree(list);}迭代器方式遍历请见下文。
三)、双端链表的迭代器
Redis 为了方便对链表的迭代,对链表进行了迭代器的封装,迭代器结构如下(以下代码定义在 src/adlist.h):
typedef struct listIter { listNode *next; //迭代器指向的下一个节点 //迭代方向,由于双端链表保存了head和tail的值,所以可以进行两个方向的迭代 //AL_START_HEAD表示从头向后遍历,AL_START_TAIL表示从尾部向前遍历 int direction;} listIter;迭代器使用实例:
//l表示list结构,n表示listNode结构,listNode的值保存的是sds字符串//创建迭代器对象iter = listGetIterator(l, AL_START_HEAD);//循环获取下一个需要遍历的节点while ((n = listNext(iter))) { //输出返回的节点n的value值 printf("Node Value: %s\n", listNodeValue(n));}以上就是Redis中的双端链表的数据结构与操作的简略介绍,当然详细使用上面的不同还得要大家自己使用过才领会。如果想了解更多,欢迎关注行业资讯频道哦!
节点
迭代
结构
指向
数据
函数
代码
数据结构
尾部
指针
长度
内存
不同
两个
方式
时候
游标
类型
后继
循环
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
广州万易互联网科技有限公司
上海卓越科技互联网
互联网最新的科技
科技与互联网
今日互联网科技
互联网金融公司科技
深圳齐家互联网科技
赫美联合互联网科技
现代科技和互联网有关系吗
西藏七维空间互联网科技有限公司
广州恒生互联网科技有限
链环科技传统企业怎么转型互联网
互联网保险科技创业
长沙互联网科技
无锡工业互联网科技有限公司
广东工业互联网大赛深圳学泰科技
深圳互联网科技园地址
互联网高科技绘画
恒生科技互联网指数十大成分股
前海云享互联网科技
国智互联网科技
远信互联网科技
互联网科技博主是什么意思
宁波青枫互联网科技有限公司
移动互联网年度科技创新
恒生互联网科技指数跳水
科技大学互联网
兰石爱特工业互联网科技分公司
福仕德教育科技互联网
每日互联网科技新闻