redis列表对象
2019-11-27 本文已影响0人
快点给我想个名
内容来自:
《redis设计与实现》购买本书请访问: 京东商城
《Redis 深度历险:核心原理与应用实践》购买本书请访问: 京东商城
列表对象的编码可以是 ziplist
或者 linkedlist
-
ziplist
ziplist
编码的列表对象使用压缩列表作为底层实现, 每个压缩列表节点(entry)保存了一个列表元素假设命令如下:
RPUSH numbers 1 "three" 5
则结构如下图:
ziplist编码的对象
-
linkedlist
linklist编码的对象linkedlist
编码的列表对象使用双端链表作为底层实现, 每个双端链表节点(node)都保存了一个字符串对象, 而每个字符串对象都保存了一个列表元素。
如果上图命令使用的不是ziplist
编码, 而是linkedlist
。则结构如下图:
StringObject
是如下的结构:
StringObject对象
-
编码转换
当列表对象可以同时满足以下两个条件时, 列表对象使用
ziplist
编码:-
列表对象保存的所有字符串元素的长度都小于
64
字节 -
列表对象保存的元素数量小于
512
个
以上两个条件的上限值是可以修改的, 具体请看配置文件中关于
list-max-ziplist-value
选项和list-max-ziplist-entries
选项的说明。对于使用
ziplist
编码的列表对象来说, 当使用ziplist
编码所需的两个条件的任意一个不能被满足时, 对象的编码转换操作就会被执行: 原本保存在压缩列表里的所有列表元素都会被转移并保存到双端链表里面, 对象的编码也会从ziplist
变为linkedlist
-
-
列表部门命令实现
命令 ziplist
编码的实现方法linkedlist
编码的实现方法LPUSH 调用 ziplistPush
函数, 将新元素推入到压缩列表的表头。调用 listAddNodeHead
函数, 将新元素推入到双端链表的表头。RPUSH 调用 ziplistPush
函数, 将新元素推入到压缩列表的表尾。调用 listAddNodeTail
函数, 将新元素推入到双端链表的表尾。LPOP 调用 ziplistIndex
函数定位压缩列表的表头节点, 在向用户返回节点所保存的元素之后, 调用ziplistDelete
函数删除表头节点。调用 listFirst
函数定位双端链表的表头节点, 在向用户返回节点所保存的元素之后, 调用listDelNode
函数删除表头节点。RPOP 调用 ziplistIndex
函数定位压缩列表的表尾节点, 在向用户返回节点所保存的元素之后, 调用ziplistDelete
函数删除表尾节点。调用 listLast
函数定位双端链表的表尾节点, 在向用户返回节点所保存的元素之后, 调用listDelNode
函数删除表尾节点。LINDEX 调用 ziplistIndex
函数定位压缩列表中的指定节点, 然后返回节点所保存的元素。调用 listIndex
函数定位双端链表中的指定节点, 然后返回节点所保存的元素。LLEN 调用 ziplistLen
函数返回压缩列表的长度。调用 listLength
函数返回双端链表的长度。LINSERT 插入新节点到压缩列表的表头或者表尾时, 使用 ziplistPush
函数; 插入新节点到压缩列表的其他位置时, 使用ziplistInsert
函数。调用 listInsertNode
函数, 将新节点插入到双端链表的指定位置。LREM 遍历压缩列表节点, 并调用 ziplistDelete
函数删除包含了给定元素的节点。遍历双端链表节点, 并调用 listDelNode
函数删除包含了给定元素的节点。LTRIM 调用 ziplistDeleteRange
函数, 删除压缩列表中所有不在指定索引范围内的节点。遍历双端链表节点, 并调用 listDelNode
函数删除链表中所有不在指定索引范围内的节点。LSET 调用 ziplistDelete
函数, 先删除压缩列表指定索引上的现有节点, 然后调用ziplistInsert
函数, 将一个包含给定元素的新节点插入到相同索引上面。调用 listIndex
函数, 定位到双端链表指定索引上的节点, 然后通过赋值操作更新节点的值。