Redis双端链表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis双端链表相关的知识,希望对你有一定的参考价值。

参考技术A

本文摘抄自 redis源码学习笔记

双端链表在Redis中的地位:它作为一种 通用数据结构 ,在Redis的内部使用非常多。是 Redis列表结构的底层实现之一,也被大量Redis模块使用,用于构建其他功能

Redis双端列表的定义可以参看 adlist.h 和 adlist.c 两个文件。
与双链表定义一致,引入了链表节点,并在此基础上增加头尾节点构建双端链表。

链表节点如下定义:

链表如下定义:

listCreate

创建新链表
O(1)

listRelease

释放链表,以及该链表所包含的节点
O(N)

listDup

创建给定链表的副本
O(N)

listRotate

取出链表的表尾节点,并插入到表头
O(1)

listAddNodeHead

将包含给定值的节点添加到链表的表头
O(1)

listAddNodeTail

将包含给定值的节点添加到链表的表尾
O(1)

listInsertNode

将包含给定值的节点添加到某个节点的之前或之后
O(1)

listDelNode

删除给定节点
O(1)

listSearchKey

在链表中查找和给定 key 匹配的节点
O(N)

listIndex

给据给定索引,返回列表中相应的节点
O(N)

listLength

返回给定链表的节点数量
O(1)

listFirst

返回链表的表头节点
O(1)

listLast

返回链表的表尾节点
O(1)

listPrevNode

返回给定节点的前一个节点
O(1)

listNextNode

返回给定节点的后一个节点
O(1)

listNodeValue

返回给定节点的值
O(1)

双端列表的结构对于增加、删除 两种常用操作,复杂度降到了O(1)
这对于实现一些内部命令如LPUSH、RPOP 等平凡命令,降低了时间开销。

Redis实现了一个双端链表的迭代器,方便从两个方向对双端链表进行迭代。
沿着节点 next 指针,从表头向表尾迭代
沿着节点 prev 指针,从表尾向表头迭代

迭代器定义如下:

获取迭代器实现如下:

迭代器每次根据迭代方向,返回下一个节点。

对列表类型的键进行操作时,程序底层操作可能就是用的双端链表
比如执行 RPUSH、LPOP、LLEN 等命令。

RPUSH 的使用如下,其他命令可以查看.

将一个或多个值 value 插入到列表 key 的表尾(最右边)。
如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表尾:比如对一个空列表 mylist 执行 RPUSH mylist a b c ,得出的结果列表为 a b c ,等同于执行命令 RPUSH mylist a 、 RPUSH mylist b 、 RPUSH mylist c 。
如果 key 不存在,一个空列表会被创建并执行 RPUSH 操作。
当 key 存在但不是列表类型时,返回一个错误。

除了实现列表类型以外, 双端链表还被很多 Redis 内部模块所应用:
事务模块使用双端链表 依序保存输入的命令
服务器模块使用双端链表来 保存多个客户端
订阅/发送模块使用双端链表来保存订阅模式的多个客户端
事件模块使用双端链表来保存 时间事件

双端链表和双向链表的区别

【中文标题】双端链表和双向链表的区别【英文标题】:difference between double-ended linked lists and doubly-linked list 【发布时间】:2015-04-04 11:09:36 【问题描述】:

我不明白双端列表和双向链表之间的区别。

两者的主要区别是什么?

【问题讨论】:

【参考方案1】:

双向链表是一个列表,其中的元素都有指向列表中前后元素的指针。

根据我的理解,双端列表与双端队列相同。这是一个队列,您可以在其中添加和删除顶部和底部的项目。

【讨论】:

【参考方案2】:

在双向链表中,每个节点都有两个指针。一个朝向其下一个节点,另一个朝向其前一个节点。

在双端链表中,每个节点只有一个指向下一个节点的指针。它与单端链表的不同之处在于,它不是只有一个“头”节点,而是包含两个这种类型的指针(“first”和“last”),因此有人能够从两端向列表中插入元素它。

(最后一张图不太清楚,但抓住了两端的点。)

【讨论】:

谢谢大家,任何其他差异将不胜感激 没有其他本质区别。【参考方案3】:

单向链接它是单向的,它使用更少的内存,插入的复杂度是 O(n)。虽然双链是双向的(下一个和上一个),但它比单链表使用更多的内存,插入和删除的复杂度为 O(n)。

【讨论】:

【参考方案4】:

双端列表类似于普通的链表,但它有一个附加特性:对最后一个链接的引用以及对第一个链接的引用。 在双向链表中,每个链接都有两个对其他链接的引用,而不是一个。第一个是到下一个链接,就像在普通列表中一样。第二个是上一个链接。

【讨论】:

【参考方案5】:

在这两个列表中,有两个来自前端和后端的指针。但是双端列表不能向后移动,只能向前移动,而双向链表可以向前和向后移动。

【讨论】:

以上是关于Redis双端链表的主要内容,如果未能解决你的问题,请参考以下文章

JAVA基础——链表结构之双端链表

#yyds干货盘点# 双端链表实现队列

Java单链表双端链表有序链表实现

Java数据结构——用双端链表实现队列

Redis源码剖析和注释--- 对象系统(redisObject)

《Java数据结构与算法》笔记-CH5-链表-5用双端链表实现队列