Redis源码阅读-list双向链表

Redis源码阅读-list双向链表

​ 链表提供了高效的节点重排能力,以及顺序节点访问方式,并且节点的删除,增加都很灵活方便,但是Redis使用的C语言并不内置这种数据结构,所以Redis在adlist文件中实现了list,list在Redis中的应用非常广泛,如列表键,发布与订阅,慢查询,监视器等功能都用到了链表,Redis服务器本身也是用list来保存多个客户端的状态信息。链表的实现在adlist.h,adlist.c文件中。

list本体的实现

​ 可以看到list中定义了三个数据类型,节点类型listNode,迭代器类型listIter,链表类型list。这些和一般的list没有什么不同,不做分析。可以关注一下,list结构体中的三个自定义函数:dup,free,match。

宏定义实现的函数

Redis中大量的使用了宏定义,此处是几个以宏实现的函数。特别是对于三个自定义函数的使用,值得思考。
在这里插入图片描述

创建链表

在这里插入图片描述

清空链表/删除链表

在这里插入图片描述

在链表头部添加节点

在这里插入图片描述

在某节点前或后插入新节点

插入一个节点有点意思,我大概分析了一下,在node后面插入newnode的步骤

//先设newnode的prev和next。

//1.newnode->next=node->next;
//2.newnode->prev=node;

//再更新tail节点

//3.if(node==list->tail)list->tail=newnode;

//再更新newnode的前后节点指向的位置。

//4.newnode->next->pre=newnode;

//5.newnode->prev->next=newnode;

删除节点

//删除某一节点
void listDelNode(list *list, listNode *node)
{
   
	//删除节点不为头节点
    if (node->prev)
        node->prev->next = node->next;
    else//为头节点需要改变头节点指向
        list->head = node->next;
	//删除节点不为尾结点
    if (node->next)
        node->next->prev = node->prev;
    else//为尾结点需要改变尾结点指向
        list->tail = node->prev;
	//如果定义了节点的free函数,调用free函数
    if (list->free) list->free(node->value);
    zfree(node);
    list->len--;
}

迭代器操作

获取迭代器

//获取迭代器
listIter *listGetIterator(list *list, int direction)
{
   
    listIter *iter;
	
    if ((iter = zmalloc(sizeof(*iter))
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值