ziplist 是为了提高存储效率而设计的一种特殊编码的双向链表。它可以存储字符串或者整数,存储整数时是采用整数的二进制而不是字符串形式存储。它能在O(1)的时间复杂度下完成list两端的push和pop操作。但因为每次操作都需要重新分配内存,所以实际复杂度和ziplist的内存使用量相关。
ziplist 结构
<zlbytes><zltail><zllen><entry>...<entry><zlend>
- zlbytes 字段的类型是unit32_t, 这个字段存储的是整个ziplist所占用的内存的字节数
- zltail 字段的类型是unit32_t, 它指的是ziplist 中最后一个entry 的偏移量
- zllen 字段的类型是unit16_6,entry的数量。2bytes,如果数量小于65535,它就是实际值,如果大于,则需要逐个遍历entry才能得到实际数值
- zlend 终止字节
Entry 结构
<prevlen><encoding><entry-data> 或者 <prevlen><encoding><entry-data>
- prevlen 前一个entry 的大小
- encoding 不同的情况下值不同,用于表示当前entry 的类型和长度
- entry-data 真实用于存储entry表示的数据
- entry 中存储的是int类型时,encoding 和 entry-data 会合并在encoding 中表示,此时没有entry-data字段
prevlen 编码
当前一个元素长度小于254的时候,prevlen 长度为1个字节,值即为前一个entry的长度,如果长度大于等于254的时候,prevlen 用5个字节表示,第一个字节设置为254,后面四个字节存前一个entry的长度
encoding 编码
encoding 的长度和值根据保存的是int还是string,还有数据的长度而定;
前两位用来表示类型,当为 11 时,表示存储的是int, 其他表示存储的是string
存储 string 时:
- |00pppppp|:后六位表示string长度,entry-data 长度不能超过63;
- |01pppppp||qqqqqqqq|:后14位表示string长度,entry-data 长度不能超过16383;
- |10000000|qqqqqqqq|rrrrrrrr|ssssssss|ttttttt| 此时encoding长度为5个字节,后面的4个字节用来表示encoding中存储的字符串长度,长度不能超过2^32 – 1;
存储int 时:
- |11000000| encoding 为3个字节,后2个字节表示一个int16;
- |11010000| encoding为5个字节,后4个字节表示一个int32;
- |11100000| encoding 为9个字节,后8字节表示一个int64;
- |11110000| encoding为4个字节,后3个字节表示一个有符号整型;
- |11111110| encoding为2字节,后1个字节表示一个有符号整型;
- |1111xxxx| encoding长度就只有1个字节,xxxx表示一个0 – 12的整数值;
为什么 ziplist 特别省内存
- 普通数组每个元素占用的内存是一样的且取决于最大的那个元素
- ziplist 为了让每个元素按照实际的内容大小存储,所以增加 encoding 字段,针对不同的encoding 来袭话存储大小
- prevlen 是为了从后向前操作节点
缺点
- 不预留空间,并且在移除节点后,立即缩容,代表每次写操作都会进行内存分配操作
- 节点扩容:最坏情况下,第一个节点的扩容,会导致整个ziplist表中的后续所有节点的entry.prevlen字段扩容
原文地址:http://www.cnblogs.com/youj/p/16913632.html
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,请务用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性