Redis中的双端链表的数据结构与操作
发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,今天小编给大家分享的是Redis中的双端链表的数据结构与操作,很多人都不太了解,今天小编为了让大家更加了解Redis中的双端链表,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。adlis
千家信息网最后更新 2025年11月07日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安全错误
数据库的锁怎样保障安全
软件开发如何制作旋钮开关
魔兽世界怀旧服沉默的神庙数据库
网络安全检错
中国陨石数据库002846
如何开启数据库的悲观锁
国内服务器做棋牌安全吗
快云数据库啥意思
鲁能软件开发工资
安装数据库默认标识
csgo你不能在安全服务器游玩
重庆凡赋网络技术
聊城联想服务器总代理供应商
沈阳app软件开发制作
遂宁软件开发外包
数据库什么是无限关系
网络安全的四大内容数据安全
联通服务器怎么不卡顿
php服务器安卓
lol服务器域名
盐田区网络技术转移优点
河北迅迪网络技术服务有限公司
静海区电子网络技术诚信合作
代理服务器运行管理系统
和平区网络安全培训会
讨论网络安全的重要性英语
怎么搜索国外的旅游数据库
app软件开发的岗位
ipadvpn服务器
赛门铁克软件开发有限公司
visio画数据库逻辑图