Redis数据结构—整数集合与压缩列表

大家好,我是白泽。今天我们将学习Redis的整数集合与压缩列表这两个数据结构,且在本文中我将尽量只描述这两种结构中重要的部分,而非面面俱到,因为我学Redis数据结构的初衷是为了我能更好理解后面要讲到的Redis对象,而非真的去研究Redis深层的实现,不会过分深入,够用就好

Redis对象的实现在底层用到了我们目前讲解到的这些数据结构:简单动态字符串SDS、双端链表、字典、以及今天要讲解的整数集合与压缩列表,因此从底层数据结构开始能为我们理解Redis打下坚实的基础,成为面试杀手

整数集合的实现

整数集合是Redis用于保存整数值的集合抽象数据结构,它可以保存int16_t、int32_t、int64_t的整数值,且保证集合中不出现重复元素

contents[]数组的类型这里看上去是int8_t,但事实上contents[]的数据类型依靠encoding的属性决定(encoding可以选择为INTSET_ENC_INT16、INTSET_ENC_INT32、INTSET_ENC_INT64表示contents[]中元素的数据类型)

typedef struct intset {
uint32_t encoding; //编码方式
uint32_t length; //集合包含的元素的个数
int8_t contents[]; //保存元素的数组
} inset;

下面给出的图片是一个包含了五个int16_t类型整数值的整数集合,int16_t表示每个整数是由16位共2个字节表示,因此此时contents[]数组大小为:5 * 16 = 80位

整数集合的升级

当我们向一个已经存在的整数集合中添加元素时,如果加入的元素的数据类型比contents[]数组元素的数据类型长,则整数集合需要进行升级,举个例子,我要在上面那个大小5的16位整数集合中插入一个类型为int32_t的整数65535:

  1. 升级首先要做的是,根据新元素的长度,扩大空间,目前有5个元素,加入一个后有6个,且int16_t的元素要升级为int32_t类型(需要6 * 32 = 192位的空间),因此需要先动态分配内存空间如下:

  1. 移动元素的位置,将14632往后移动到新的位置,末尾留下一个位置存放32位的65535

  1. 同理移动233、18、-5、-6370,并最后将末尾的空间中存入65535

整数集合不支持降级

如果因为插入一个32位的整数使得原本16位的contents[]数组转变为32位,后面又删去了这个32位的整数,这个整数集合将不会降级成16位的contents[]数组

压缩列表的构成

因为压缩列表好像面试中不太出现,所以略讲~

压缩列表就是一块连续的内存,一种顺序型的数据结构,entryX是一个个节点,存放数据,其他属性用于描述整个压缩列表的整体情况(占用内存、节点个数等)

zlbytes:记录整个压缩列表占用的内存字节数

zltail:记录压缩列表表尾节点距离压缩列表的起始地址的偏移量

zllen:记录了压缩列表中节点数量

entryX:压缩列表的各个节点

zlend:特殊值0xFF,用于标记压缩列表的末端

压缩列表节点的构成

节点就是一个个的entryX,是压缩列表的核心,每个节点由三部分组成:

  1. previous_entry_length:记录前一个节点的长度,因此可以从当前节点的起始地址计算出前一个节点的起始地址,从而实现压缩列表的逆序遍历
  2. encoding:记录的content属性所保存数据的类型以及长度
  3. content:负责保存节点的值(一个字节数组或整数)

小结

到目前为止,白泽已经带大家初步学习了Redis底层所有的数据结构:简单动态字符串SDS、双端链表、字典、跳跃表、整数集合、压缩列表,下一篇博客将带大家学习Redis的对象(Redis的对象底层就是这些数据结构实现的),再后面就正式讲解Redis数据库的知识点了,敬请期待~

Redis数据结构—整数集合与压缩列表的更多相关文章

  1. Redis底层探秘(四):整数集合及压缩列表

    整数集合 整数集合(intset)是集合键的底层实现之一,当一个集合只包含 整数值元素,并且这个集合的元素数量不多时,Redis就会使用郑书记和作为集合键的底层实现. 整数集合的实现 整数集合是red ...

  2. Redis 学习笔记(篇四):整数集合和压缩列表

    整数集合 Redis 中当一个集合(set)中只包含整数,并且元素不多时,底层使用整数集合实现,否则使用字典实现. 那么: 为什么会出现整数集合呢?都使用字典存储不行吗? 整数集合在 Redis 中的 ...

  3. redis 笔记01 简单动态字符串、链表、字典、跳跃表、整数集合、压缩列表

    文中内容摘自<redis设计与实现> 简单动态字符串 1. Redis只会使用C字符串作为字面量,在大多数情况下,Redis使用SDS(Simple Dynamic String,简单动态 ...

  4. redis intset(整数集合)

    redis intset (整数集合) 概述 intset 是集合的底层实现结构之一 intset 集合只包含整数 intset 自升级 intset 整数集合是有序的 intset 结构 结构 // ...

  5. redis 底层数据结构 整数集合intset

    整数集合是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时Redis就会使用整数集合作为集合键的底层实现 整数集合是Redis用于保存整数值的集合抽象数据结构,它可以保存 ...

  6. Redis原理再学习05:数据结构-整数集合intset

    intset介绍 intset 整数集合,当一个集合只有整数元素,且元素数量不多时,Redis 就会用整数集合作为集合键的底层实现. redis> SADD numbers 1 3 5 7 9 ...

  7. 多图解释Redis的整数集合intset升级过程

    redis源码分析系列文章 [Redis源码系列]在Liunx安装和常见API 为什么要从Redis源码分析 String底层实现——动态字符串SDS 双向链表都不懂,还说懂Redis? 面试官:说说 ...

  8. 图解Redis之数据结构篇——压缩列表

    前言     同整数集合一样压缩列表也不是基础数据结构,而是 Redis 自己设计的一种数据存储结构.它有点儿类似数组,通过一片连续的内存空间,来存储数据.不过,它跟数组不同的一点是,它允许存储的数据 ...

  9. Redis 源码简洁剖析 05 - ziplist 压缩列表

    ziplist 是什么 Redis 哪些数据结构使用了 ziplist? ziplist 特点 优点 缺点 ziplist 数据结构 ziplist 节点 pre_entry_length encod ...

随机推荐

  1. P1008_三连击(JAVA语言)

    /*  * 题目描述 将1,2,⋯,9共9个数分成3组, 分别组成3个三位数,且使这3个三位数构成1:2:3的比例,试求出所有满足条件的3个三位数. 输入输出格式 输入格式: 木有输入 输出格式: 若 ...

  2. Redis入门到放弃系列-redis数据类型

    Redis数据类型? Redis 提供一些常用的数据类型:Strings.Lists.Sets.Sorted sets.Hashes.Arrays.Bitmap.Streams Strings(字符串 ...

  3. python多版本与虚拟环境

    这篇纯python技术文章,我自己平时也会用到,在此记录一下. 为什么会用到多个Python版本? 用macOS和Ubutntu的同学都知道系统默认安装的Python2.7.x,然后,我们平时pyth ...

  4. MyBatis-Plus Generator自定义模板

    相信大家在开发过程中,应该都用过Mybatis-Plus的Generator,但是可能没有自定义过模板并使用. 每个项目都应该有一个从Controller层到Mapper层的通用模板,来去掉哪些简单的 ...

  5. 基于Hive进行数仓建设的资源元数据信息统计:Hive篇

    在数据仓库建设中,元数据管理是非常重要的环节之一.根据Kimball的数据仓库理论,可以将元数据分为这三类: 技术元数据,如表的存储结构结构.文件的路径 业务元数据,如血缘关系.业务的归属 过程元数据 ...

  6. 201871030112-贾傲羊 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    项目 内容 课程班级博客链接 课程班级博客链接 这个作业要求链接 作业要求链接 我的课程学习目标 学习PSP流程并运用于结对项目:学习GitHub代码的管理;学习结对编程的流程与内容 这个作业在哪些方 ...

  7. Java基础 - List的两个子类的特点

    List两个子类的特点 List的两个子类的特点 因为两个类都实现了List接口,所以里面的方法都差不多,那这两个类都有什么特点呢? ArrayList: 底层数据结构是数组,查询快,增删慢. Lin ...

  8. 2.EL表达式&JSTL标签库常用方法

    1.EL表达式 Expression Language表达式语言,主要是代替jsp页面中的表达式脚本在jsp页面中进行数据的输出. 格式为${表达式} EL表达式输出Bean的普通属性.数组属性.Li ...

  9. 如何在CSS中映射的鼠标位置,并实现通过鼠标移动控制页面元素效果

    映射鼠标位置或实现拖拽效果,我们可以在 JavaScript 中做到这一点.但实际上,在CSS中有更加简洁的方法,我们可以在不使用JavaScript 的情况下,仍然可以实现相同的功能! 只使用CSS ...

  10. JDBC_10_使用Statement实现升序和降序

    使用Statement数据库操作对象实现升序和降序 Statement可以使用在需要SQL语句拼接的情况下,因为在这样的情况下如果使用PreparedStatement就会给需要拼接的某个SQL关键字 ...