Redis(设计与实现):09---对象之列表对象(list)
原创
©著作权归作者所有:来自51CTO博客作者董哥的黑板报的原创作品,请联系作者获取转载授权,否则将追究法律责任
一、列表对象的编码
- 列表对象的编码可以是ziplist或者linkedlist
ziplist型编码
- ziplist编码的列表对象使用压缩列表作为底层实现,每个压缩列表节点(entry)保存了一个列表元素
- 举个例子,如果我们执行以下RPUSH命令,那么服务器将创建一个列表对象作为numbers键的值,如果numbers键的值对象使用的是ziplist编码,这个值对象将会是下图所展示的样子:
linkedlist型编码
- linkedlist编码的列表对象使用双端链表作为底层实现,每个双端链表节点 (node)都保存了一个字符串对象,而每个字符串对象都保存了一个列表元素
- 注意,linkedlist编码的列表对象在底层的双端链表结构中包含了多个字符串对象,这种嵌套字符串对象的行为在稍后介绍的哈希对象、集合对象和有序集合对象中都会出现,字符串对象是Redis五种类型的对象中唯一一种会被其他四种类型对象嵌套的对象
- 举个例子,如果上面我们所说的numbers键创建的列表对象使用的不是ziplist编码,而是linkedlist编码,那么numbers键的值对象将是下图所示的样子:
- 备注:上图中的StringObject字样的格子是我们对字符串对象的简化模式,例如双端链表中的StringObject字样的格子应该是下面所示的样子
二、编码转换
编码的规则
- ziplist编码的规则如下:
- 列表对象保存的所有字符串元素的长度都小于64字节
- 列表对象保存的元素数量小于512个
- linkedlist编码的规则:
- 不能满足上面那两个条件的列表对象需要使用linkedlist编码
配置选项
- 以上两个条件的上限值是可以修改的,具体请看配置文件中关于list-max-ziplist-value选项和list-max-ziplist-entries选项的说明
演示案例
- 下面的代码演示了列表对象因为保存了长度太大的元素而从ziplist编码转换为linkedlist编码的情况:
- 以下代码展示了列表对象因为保存的元素数量过多而从ziplist编码转换为linkedlist编码的情况:
三、列表命令的实现
- 因为列表键的值为列表对象,所以用于列表键的所有命令都是针对列表对象来构建的, 下表列出了其中一部分列表键命令,以及这些命令在不同编码的列表对象下的实现方法