Redis数据结构-压缩列表

214 阅读4分钟
一、压缩列表的底层实现
压缩列表是哈希键和列表键的底层实现之一。压缩列表是为了节约内存而开发的,是由特殊编码的连续内存块组成的顺序性数据结构;可以包含任意多个节点,每个节点包含一个字节数组或者一个整数值。
当列表键中包含的条目较少并且条目都是小整数或者短字符串,那么列表键就会选择压缩列表作为底层实现。
当哈希键中包含的键值对较少,并且键值对都是小整数或者短字符串,那么哈希键就会选择压缩列表作为底层实现。

压缩列表的结构:
zlbytes
zltail
zllen
entry1
entry2
......
entryN
zlend

属性
类型
长度
说明
zlbytes
uint32_t
4字节
压缩列表所占用的内存字节数
zltail
uint32_t
4字节
记录压缩列表最后一个节点的内存地址距压缩列表起始地址的偏移量
zllen
uint16_t
2字节
压缩列表中节点的数量
entry
列表节点
不定
压缩列表中的节点,节点的长度由其中保存的内容决定
zlend
uint8_t
1字节
0xFF(255)标志压缩列表的结尾

二、压缩列表节点的构成
previous_entry_length
encoding
content
每个压缩列表的节点可以保存一个字节数组或一个整数值。

1. previous_entry_length
previous_entry_length记录了前一个节点的长度;该属性的大小可能是1字节或5字节。
  • 如果前一个节点的长度小于254,则该属性用1个字节表示
  • 如果前一个节点的长度不小于254,则该属性用5个字节表示;第一个字节用0xFE表示,标志这是一个五字节长的属性。

2. encoding
encoding属性记录了content所保存的内容的类型及长度。

编码
编码长度
content保存的值的类型
content保存的值的长度
说明
00xxxxxx
1字节
字节数组
<= 2^6-1
00表示编码长度为8位的字节数组,后6位表示content的长度
01xxxxxx xxxxxxxx
2字节
字节数组
<= 2^14-1
01表示编码的长度位16位的字节数组,后14位表示content的长度
10_____ xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
5字节
字节数组
<= 2^32-1
10表示编码的长度位40位的字节数组,后32位表示content的长度
11000000
1字节
int16_t类型整数
int16_t
11表示content的类型为整数,后6位表示content的长度位2字节
11010000
1字节
int32_t类型整数
int32_t
-
11100000
1字节
int64_t类型整数
int64_t
-
11110000
1字节
24位有符号整数
24位
-
11111110
1字节
8位有符号整数
8位
-
1111xxxx
1字节
没有content属性
0
后4位记录了0-12的整数

3. content
content保存着节点的值,节点的值可以是字节数组或整数,值的类型和长度由encoding属性决定。
字节数组示例:
previous_entry_length
encoding
content
......
00001011
"hello world"

整数示例:
previous_entry_length
encoding
content
......
110000000
10086

三、连锁更新
在插入节点时,如果新插入的节点的长度大于下一个节点previous_entry_length的长度,就会重新分配内存,以满足需求,如果后面的节点因此也发生了内存重新分配,称为连锁更新。
连锁更新最坏的时间复杂度为O(n^2),尽管连锁更新的复杂度较高,但是真正引发连锁更新的几率很低。


四、API
函数
作用
时间复杂度
ziplistNew
创建一个新的压缩列表
O(1)
ziplistPush
在表头或表尾添加一个新的节点
平均O(n),最坏O(n^2)
ziplistInsert
在指定节点之后插入一个新节点
平均O(n),最坏O(n^2)
ziplistIndex
返回指定索引上的节点
O(n)
ziplistFind
查找指定值的节点
O(n^2)
ziplistNext
指定节点的下一个节点
O(1)
ziplistPrev
指定节点的前一个节点
O(1)
ziplistGet
获取指定节点的值
O(1)
ziplistDelete
删除指定的节点
平均O(n),最坏O(n^2)
ziplistDeleteRange
删除指定索引范围的节点
平均O(n),最坏O(n^2)
ziplistLen
压缩列表节点数量
O(1)
ziplistBlobLen
压缩列表所占用内存的字节数
O(1)