redis 源代码之数据结构(5)--ziplist实现
来源:互联网 发布:大数据人才的薪资待遇 编辑:程序博客网 时间:2024/05/18 19:46
上一篇分析了zipmap的源代码,zipmap在redis中比较鸡肋,实际上,在2.6版本中,并没有使用zipmap数据结构,zipmap可以用ziplist来进行替代。ziplist用字符串实现了双链表,非常节约内存,既可以存储字符串,也可以存储整型。对ziplist两端进行pop和push操作可以在O(1)时间内完成。但是,每次对ziplist的操作,可能会需要对list进行realloc,所以复杂度和ziplist占用的内存大小相关。
ziplist的内存布局:
<zlbytes><zltail><zllen><entry><entry><zlend>
<zlbytes>表示ziplist所占用的总字节数;<zltail>表示ziplist的最后一个entry的偏移(相对于开头),加入这个字段,主要是为pop操作可以在O(1)时间内完成。<zllen>表示entry的链表节点个数,但是,当节点数大于2^16-2,只能通过遍历得到链表长度。<zlend>是一个标志字节,等于255,暗示链表的结尾。
我们来看看ziplist的节点数据结构:
typedef struct zlentry { unsigned int prevrawlensize, prevrawlen; unsigned int lensize, len; unsigned int headersize; unsigned char encoding; unsigned char *p;} zlentry;prevrawlensize是存储前一个节点长度所需要的字节数 ,prevrawlen存储的是前一个节点的占用字节数,这样可以从后往前遍历(双向链表)。
lensize是存储当前节点长度所需要的字节数,len是当前节点占用的字节数。
headersize 当前节点 头部大小
encoding表示当前节点的len字段的编码类型。
p 指向当前节点的起始位置。
ziplist节点存储结构
<上一个节点占用的长度><当前链表节点占用的长度><当前节点数据>
<上一个节点占用的长度> 根据这个数值,可以往前遍历,实现双向链表。如果前节点小于254,就用1个字节表示之,否则就用5个字节表示上一个节点的长度,其中第一个字节数值是254,其余的四字节表示上一个节点的真正长度。
<当前链表节点占用的长度> 第一个字节的前两位表示数据类型。具体编码如下:
|00pppppp| - 1 byte 字符串编码类型,字符串最大长度是63字节 |01pppppp|qqqqqqqq| - 2 bytes 字符串编码类型, 最大长度是 16383 bytes (14 bits). |10______|qqqqqqqq|rrrrrrrr|ssssssss|tttttttt| - 5 bytes 字符串编码模型,最小长度是16384。 |11000000| - 1 byte 整型编码,紧随其后的2字节是长度数值 int16_t (2 bytes). |11010000| - 1 byte 整型编码,紧随其后的4字节是长度数值 encoded as int32_t (4 bytes). |11100000| - 1 byte 整型编码,紧随其后的8字节是长度数值 encoded as int64_t (8 bytes). |11110000| - 1 byte 整型编码,紧随其后的3字节是长度数值 encoded as 24 bit signed (3 bytes). |11111110| - 1 byte 整型编码,紧随其后的2字节是长度数值 encoded as 8 bit signed (1 byte). |1111xxxx| - (with xxxx between 0000 and 1101) immediate 4 bit integer. Unsigned integer from 0 to 12. 我勒个去,这13个数还不放弃,实际上是从数值直接读取的是1~13,所以要减去1,才能得到编码值。 |11111111| - 链表的结尾
- redis 源代码之数据结构(5)--ziplist实现
- Redis 数据结构之ziplist
- redis源码分析(八)、redis数据结构之压缩ziplist--------ziplist.c ziplist.h学习笔记
- 【Redis源码剖析】 - Redis内置数据结构之压缩列表ziplist
- redis之ziplist
- redis之ziplist
- Redis内部数据结构详解之压缩链表(ziplist)
- Redis内部数据结构详解之压缩链表(ziplist)
- 深入剖析 redis 数据结构 ziplist
- Redis-数据结构-压缩列表-ziplist
- redis 源代码之数据结构(2)--sds实现
- redis 源代码之数据结构(4)--zipmap实现
- redis源码系列-数据结构(adlist/ziplist/dict)
- Redis内部数据结构总结(3)ziplist
- redis ziplist
- redis 源代码之数据结构(1)--链表的实现
- redis 源代码之数据结构(3)--hash表实现
- redis 源代码之数据结构(sds,链表的实现)
- tasklet 工作队列 内核定时器 内核线程
- UIView动画(过渡效果)的学习笔记
- Linux多线程Pthread学习小结
- 1934: [Shoi2007]Vote 善意的投票 (网络流)
- oracle学习记录之授权(2)
- redis 源代码之数据结构(5)--ziplist实现
- 分治算法总结
- 将 Win32 程序移植到 Linux
- hibernate入门-02
- 使用keychain保存用户名和密码等敏感信息 KeychainItemWrapper和SFHFKeychainUtils。
- 深入分析Windows和Linux动态库应用异同
- DataSet DataTable DataReader dataAdapter区别 (转载)
- select,poll,epoll区别
- C#验证码类代码