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. golang float32/64转string

    v := 3.1415926535 s1 := strconv.FormatFloat(v, 'E', -1, 32)//float32s2 := strconv.FormatFloat(v, 'E' ...

  2. RabbitMQ 入门 (Go) - 2. 发布和接收消息

    本文我将使用 Go 语言在 RabbitMQ 上发布和接收消息. Go 的标准库本身并没有 RabbitMQ 的原生绑定,但是有一个第三方库确能够支持 RabbitMQ,它的源码在 https://g ...

  3. Webpack的基本配置和打包与介绍

    1. 前言 1.1 Webpack是什么 可能有很多的小伙伴对于这个Webpack既熟悉又陌生,有一些刚开始接触vue的小伙伴在对项目进行打包的时候经常会使用到npm run build来进行打包,但 ...

  4. OO第三单元个人总结

    OO第三单元个人总结 JML理论与基础与应用工具链 JML是什么? Java建模语言(JML)是一种行为接口规范语言,可用于指定Java模块的行为 .它结合了Eiffel的契约设计方法 和Larch ...

  5. Hadoop完整搭建过程(一):本地模式

    1 本地模式 本地模式是最简单的模式,所有模块都运行在一个JVM进程中,使用本地文件系统而不是HDFS. 本地模式主要是用于本地开发过程中的运行调试用,下载后的Hadoop不需要设置默认就是本地模式. ...

  6. 【Redis破障之路】二:Redis安装和基本数据结构

    1.安装Redis Redis6.0在2020年已经发布,所以我们安装Redis3.0. 1.1.在Linux上安装Redis 我们在CentOS上安装Redis.常见的的有三种安装方式: yum/a ...

  7. 如何查看显著性SNP在数据中的频率?

    我们做完GWAS的关联分析后需要查看显著性SNP在我们数据中的频率分布情况.这时候我们需要用到plink和我们做关系分析所用的二进制文件datas. 第一步,我们用R语言读取分析结果,即*.assoc ...

  8. Day11_52_将Set集合转换为List集合

    Set集合转换为List集合 ``` import java.util.*; public class SetReverseLsit { public static void main(String[ ...

  9. 幻读:听说有人认为我是被MVCC干掉的

    @ 目录 前言 系列文章 一.我是谁? 二.为什么有人会认为我是被MVCC干掉的 三.我真的是被MVCC解决的? 四.再聊当前读.快照读 当前读 快照读 五.告诉你们吧!当前读的情况下我是被next- ...

  10. 【cypress】4. 丰富的调试工具

    Cypress附带了一系列调试工具来帮助我们弄明白测试的经过,利于我们更好的调试. 具体这些工具的能力都有啥? 回到每个命令的快照. 可以看到特殊的已发生的page events. 接收关于每个命令的 ...