hash
以后都在 github 更新,请戳 redis 哈希结构实现(ziplist/ht)
目录
相关位置文件
- redis/src/ziplist.h
- redis/src/ziplist.c
- redis/src/dict.h
- redis/src/dict.c
encoding
OBJ_ENCODING_ZIPLIST
ziplist 是一种特殊的双端链表, 它能最大程度地节省内存空间. 它可以存储字符串和整型值, 整型的存储方式是真正的整数, 而不是一串整数的字符串表示, 它也可以在任意一端进行压入/弹出操作, 并且该操作的时间复杂度为 O(1). 但是每一个操作都需要对这个 ziplist 的空间进行重新分配, 实际上真正的复杂度是和 ziplist 使用到的空间相关的
翻译自 redis/src/ziplist.c
这是 ziplist 的内存构造
[外链图片转存失败(img-PVSO61Za-1566351858954)(https://github.com/zpoint/Redis-Internals/blob/5.0/Object/hash/ziplist_overall_layout.png)]
我们来看一个简单的示例
127.0.0.1:6379> HSET AA key1 33
(integer) 1
127.0.0.1:6379> OBJECT ENCODING AA
"ziplist"
[外链图片转存失败(img-F7sM0f7Q-1566351858955)(https://github.com/zpoint/Redis-Internals/blob/5.0/Object/hash/simple_hash.png)]
从上图我们可以看出
zlbytes
表示当前这个 ziplist 总共占用的字节数
zltail
是从当前位置到达 zlend
的字节偏移量
zllen
表示当前这个 ziplist 有多少个 entries
zlend
是一个长度为一字节的结束标记, 表示 ziplist 的尾端
这是上面插入过后的内存构造
[外链图片转存失败(img-iV1xh4lH-1566351858957)(https://github.com/zpoint/Redis-Internals/blob/5.0/Object/hash/simple_hash_two_entry.png)]
prevlen
存储的是前一个 entry 占用的字节长度, 通过这个字段你可以反方向遍历这个双端链表, 这个字段本身的长度要么就是一个 1 字节长的 uint8_t
表示前一个 entry 的长度在 254 bytes 以下, 要么是一个 5 字节长的数, 第一个字节用来作为标记区分前一种表示方法, 后面的 4 个字节可以作为 uint32_t
表示前一个 entry 占用的字节数
encoding
表示的是 entry 中的内容是如何进行编码的, 当前存在好几种不同的 encoding
, 我们后面会看到
entry
我们现在知道了 entry 包含了 3 个部分