ziplist 是列表键和哈希表底层实现之一
当一个列表键只包含少量列表项,且每个列表项是小整数值或者长度比较短的字符串时会使用 ziplist
127.0.0.1:6379> rpush lst 1 3 5 10086 "hello" "world"
(integer) 6
127.0.0.1:6379> OBject encoding lst
"ziplist"
?
节约内存,一系列特殊编码的连续内存块组成的顺序型数据结构
一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或一个整数值
例子:
每个压缩列表节点可以保存一个字节数组或者一个整数值
字节数组可以是以下一种
整数可以是:
previous_entry_length 字节为单位,记录压缩列表前一个字节的长度,本身长度可以是 1 字节或 5 字节
可以通过当前节点的起始地址来计算前一个节点的起始地址,压缩列表的从表尾向表头遍历操作就是使用这一原理的,
encoding 记录节点的 content 属性所保存数据的类型以及长度
假如 e1 - eN 都是 250-253 字节,添加新节点 new ,且大小大于 254 字节,此时 e1 的previous_entry_length 只是 1 字节,于是需要重新分配内存空间,e1 的总长度变化,可能超过 254 字节,于是 e2 变化,直到 eN
这种特殊情况下产生的连续多次空间扩展操作称之为“连锁更新”
同理,删除节点也可能引发连锁更新
连锁更新最坏情况下需要对压缩列表执行 N 次空间重分配操作,每次重分配操作的时间复杂度为 O(n),所以连锁更新最坏情况下是 O(n^2)
虽然时间复杂度高,但几率是佷低的
ziplistPush 平均复杂度为 O(n)
原文:https://www.cnblogs.com/zephxu/p/14891623.html