Redis的数据结构与对象——压缩列表

前言:压缩列表是列表键、哈希键、有序集合的底层实现之一。

当一个列表键只包含少量列表项,并且每个项要么是小整数或者短字符串的时候,redis使用压缩列表来实现列表键。

当一个哈希键只包含少量键值对,并且每个键值对要么是小整数值,要么是短字符串,redis使用压缩列表实现哈希键。

一、实现

    压缩列表是redis为了节约内存而开发的,是由一系列特殊编码的连续内存块组成的顺序性数据型数据结构。一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或者一个整数值

1.1、压缩列表

压缩列表


压缩列表各字段的含义


1.2、压缩列表节点


压缩列表节点

1、pre_entry_length 记录了前一个节点的长度,通过这个值,可以进行指针计算,从而跳转到上一个节点。只要用指针减去当前节点pre_entry_length 值,就可以得出前一个节点的指针。压缩列表从节点尾部想头部遍历就是利用这一点。

2、encoding 决定了 content 部分所保存的数据的类型以及长度。

encoding

3、content负责保存节点的值,节点值可以是一个字节数组或者整数。


二、连锁更新

添加和删除 ziplist 节点有可能会引起连锁更新,因此,添加和删除操作的最坏复杂度为 O(N^2) ,不过,因为连锁更新的出现概率并不高,所以一般可以将添加和删除操作的复杂度视为 O(N)。

为什么会连锁更新?

主要是因为pre_entry_length记录了前一个节点的长度,

如果前一个节点长度小于等于254字节,pre_entry_length将会是1个字节长度。

如果前一个节点长度大于254字节,pre_entry_length将会是5个字节长度。

如果有一种情况:压缩列表中有多个连续250-253字节的节点。由于都是这么长,所以这些节点的pre_entry_length都是一个字节,但是突然插入了一个新的节点,他的长度超过了254个字节,那么所有的节点的pre_entry_length都要变成5个字节,一个一个连锁反应,都要改变。

当然,删除节点也会引起这样的变化。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 正文    压缩列表(Ziplist )是列表键和哈希键的底层实现之一   当一个列表键只包含少量列表项,并且每个...
    于情于你阅读 2,523评论 0 1
  • 构成 压缩列表是 Redis 为了节约内存而开发的, 由一系列特殊编码的连续内存块组成的顺序型(sequentia...
    来年花惜阅读 6,657评论 0 2
  • 压缩列表(ziplist)是列表和哈希键的底层实现之一。 1 压缩列表的构成 压缩列表是Redis节约成本而开发,...
    HRADPX阅读 2,738评论 0 0
  • 一、String 1.1.数据结构 注:数组大小=len+free+1(字符的‘\0’休止符) 1.2.空间分配策...
    爱情小傻蛋阅读 5,678评论 2 0
  • 童话里,王子总是能在角落里找到他的灰姑娘。电视剧里,傻不拉叽的女主总能被她帅气多金的男主捧在手心。这些童话、剧本让...
    lawyer无畏阅读 864评论 0 1