codecamp

Redis双端链表

双端链表

链表作为数组之外的一种常用序列抽象,是大多数高级语言的基本数据类型,因为 C 语言本身不支持链表类型,大部分 C 程序都会自己实现一种链表类型,Redis 也不例外 —— 实现了一个双端链表结构。

双端链表作为一种常见的数据结构,在大部分的数据结构或者算法书里都有讲解,因此,这一章关注的是 Redis 双端链表的具体实现,以及该实现的 API ,而对于双端链表本身,以及双端链表所对应的算法,则不做任何解释。

读者如果有需要的话,可以参考维基百科的双端链表 词条,里面提供了关于双端链表的一些基本信息。

另外,一些书籍,比如《算法:C 语言实现》《数据结构与算法分析》 则提供了关于双端链表的更详细的信息。

双端链表的应用

双端链表作为一种通用的数据结构,在 Redis 内部使用得非常多:既是 Redis 列表结构的底层实现之一,同时为大量 Redis 模块所用,用于构建 Redis 的其他功能。

实现 Redis 的列表类型

双端链表还是 Redis 列表类型的底层实现之一,当对列表类型的键进行操作 ——比如执行 RPUSHLPOPLLEN 等命令时,程序在底层操作的可能就是双端链表。

redis> RPUSH brands Apple Microsoft Google
(integer) 3

redis> LPOP brands
"Apple"

redis> LLEN brands
(integer) 2

redis> LRANGE brands 0 -1
1) "Microsoft"
2) "Google"

Note

Redis 列表使用两种数据结构作为底层实现:

  1. 双端链表
  2. 压缩列表

因为双端链表占用的内存比压缩列表要多,所以当创建新的列表键时,列表会优先考虑使用压缩列表作为底层实现,并且在有需要的时候,才从压缩列表实现转换到双端链表实现。

后续章节会对压缩链表和 Redis 类型做更进一步的介绍。

Redis 自身功能的构建

除了实现列表类型以外,双端链表还被很多 Redis 内部模块所应用:

  • 事务模块使用双端链表依序保存输入的命令;
  • 服务器模块使用双端链表来保存多个客户端;
  • 订阅/发送模块使用双端链表来保存订阅模式的多个客户端;
  • 事件模块使用双端链表来保存时间事件(time event);

类似的应用还有很多,在后续的章节中我们将看到,双端链表在 Redis 中发挥着重要的作用。

双端链表的实现

双端链表的实现由 listNodelist 两个数据结构构成,下图展示了由这两个结构组成的一个双端链表实例:

Redis简单动态字符串
Redis 字典
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

第二部分:内存映射数据结构

第五部分:内部运作机制

RDB
AOF

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }