redis数据结构源码分析——压缩列表ziplist(I)

前面讲了跳表的源码分析,本篇我们来聊一聊另外一个重点结构——压缩列表

文章目录

  • 存储结构
    • 字节数组结构
    • 节点结构
  • 压缩编码
    • zipEntry
      • zlEntry
    • ZIP_DECODE_PREVLEN
    • ZIP_DECODE_LENGTH
  • API解析
    • ziplistNew(创建压缩列表)
    • ziplistInsert(插入)
    • ziplistDelete(删除)
    • ziplistFind(查找)
  • 压缩列表的设计思想和优势
    • 设计思想
    • 优势

存储结构

字节数组结构

压缩列表就是一个字节数组(char *zl)
有序集合、散列和列表都直接或间接使用到压缩列表
在这里插入图片描述
zlbytes:压缩列表的字节长度
zltail:压缩列表尾元素相对于压缩列表起始地址的偏移量
zllen:压缩列表的元素个数
entry:各个节点
zlend:压缩列表的结尾,占一个字节,一直是0xFF(255)

节点结构

也就是entry里存的是什么
在这里插入图片描述
网上很多这样的图,那么这个结构是哪里来的呢?我们看下源码中的注释:
在这里插入图片描述
prevlen:前一个元素的字节长度
encoding:当前元素的编码,占一个字节,八位。前两位存的是元数据的类型,后六位存的是元数据的长度
entry-data:元数据,也就是当前的内容
prevlen和encoding这两部分是作为元数据的前缀信息。注意!这里的注释说了,通常情况下是这样的结构,但也有其他情况:
在这里插入图片描述
有时候encoding代表entry本身,比如说小整数(0-12),在这种情况下,是没有entry-data的
这里的注释能看出来编码的实际样式,简单翻译一下:

压缩编码

zipEntry

zlEntry

zipEntry解压完后是zlEntry
在这里插入图片描述
prevrawlensize:存储prevrawlen需要的字节数
prevrawlen:前一个节点占用的字节数
lensize:存储len需要的字节数
len:数据长度
headersize:首部长度,等于prevrawlensize + lensize
encoding:当前元素编码
*p:当前元素首地址

ZIP_DECODE_PREVLEN

用来解码prevlen字段
根据注释我们可以了解prevlen
在这里插入图片描述
我们大概翻译一下这里的注释:如果prevlen长度小于254字节,就只消耗单个将长度表示为无符号8位整数的字节。当长度大于或等于254,则它将消耗5个字节。第一个字节是设置为254(FE)以指示后面是更大的值。剩下的4个字节将上一个条目的长度作为值。
我们看下代码:
在这里插入图片描述
其实从这里可以看出,这个值要么是1要么是5.
大概流程可以这样表示:
在这里插入图片描述

ZIP_DECODE_LENGTH

用来解码encoding字段
在这里插入图片描述
这里的代码比较长,但是能看出来,就是根据传入的当前元素和encoding求len和lensize

API解析

这里我们大概讲下以下四个API,后三个插入删除和查找的源码较长,我们本篇只做大概讲解,详细的讲解在这里:redis源码解析——压缩列表ziplist(II)API详解+级联更新

ziplistNew(创建压缩列表)

在这里插入图片描述
这块是比较简单的,大概步骤如下:
1、计算长度
2、根据计算出的长度申请内存(zmalloc方法)
3、各个字段赋初始值
4、返回字节数组的地址
这里的zmalloc方法就是分配内存作用
在这里插入图片描述

ziplistInsert(插入)

在这里插入图片描述
这里的__ziplistInsert方法比较复杂,我们后续可以专门出一篇文章讲解下,这里就做个步骤的大概梳理:
1、编码
2、重新分配空间
3、数据复制

ziplistDelete(删除)

在这里插入图片描述
这里相对于插入来说是比较简单的,不过详细源码解析我们跟插入流程一起出一篇讲解,这里的大概流程为:
1、先计算出要删除的元素的长度
2、数据复制
3、重新分配空间

ziplistFind(查找)

1、计算节点属性
2、判断节点类型
3、如果是字符串,对比内容
4、如果是整数,对比数值
5、找到就返回,找不到就指向下一个

压缩列表的设计思想和优势

设计思想

1、为了节省空间而设计
2、内存是连续的,元素之间没有空隙
3、encoding不仅存类型,也可以存长度
4、不存储前后节点的指针,并不是通过索引来找位置,而是通过长度计算前后节点的位置
5、zlentry的解码存储

优势

1、节省内存,其实也就是以时间换空间。相对来说更适用于比较小的数据或是说比较少的数据量大场景
2、zlentry可以提供快速访问

2023过去了,祝愿各位朋友们2024龙年大吉,技术越来越好,也希望自己在新的一年里技术提升,工作顺利。最近写redis的源码系列看了不少文章,这里给大家提个建议,看到网上的文章或教学时,不要完全的跟着教学走,比如这里的entry结构,一定要带着怀疑的态度自己去翻翻源码,我原本也是看到网上的文章,但是看到entry结构时,看了很多文章都是过于八股,没有一篇文章讲的是明白的,所以还是建议大家带着怀疑的心态学习。
最后,有任何疑问或不同意见,欢迎留言讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/702991.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

复旦大学EMBA联合澎湃科技:共议科技迭代 创新破局

1月18日,由复旦大学管理学院、澎湃新闻、厦门市科学技术局联合主办,复旦大学EMBA项目、澎湃科技承办的“君子知道”复旦大学EMBA前沿论坛在厦门成功举办。此次论坛主题为“科技迭代 创新破局”,上海、厦门两地的政策研究专家、科学家、科创企…

2024年漳州本地有正规等保测评机构吗?在哪里?

我们大家都知道,企业办理等保一定要找有资质的等保测评机构。因此不少漳州企业在问,2024年漳州本地有正规等保测评机构吗?在哪里?这里我们小编通过查找来为大家解答一下,仅供参考! 目前福建漳州本地没有正规…

HTTP---------状态码

当服务端返回 HTTP 响应时,会带有一个状态码,用于表示特定的请求结果。比如 HTTP/1.1 200 OK,里面的 HTTP/1.1 表示协议版本,200 则是状态码,OK 则是对状态码的描述。 由协议版本、状态码、描述信息组成的行被称为起始…

北京硒鼓耗材回收价位,硒鼓回收价格,回收

联系我的时候请说是在百猫网看到的! 硒鼓回收价格:最专业的硒鼓回收 顺达耗材回收 俗话说,顾客是最好的,良好的品牌效应是推动发展的关键之一。 北京顺达耗材回收有限公司为中小企业创造良好的二手消费市场,不断贯彻…

皓学IT:MySQL02

一、了解表 1.1.概述 表是处理数据和建立关系型数据库及应用程序的基本单元,是构成数据库的基本元素之一,是数据库中数据组织并储存的单元,所有的数据都能以表格的形式组织,目的是可读性强。 1.2.表结构简述 一个表中包括行和列…

Uncertainty-Aware Mean Teacher(UA-MT)

Uncertainty-Aware Mean Teacher 0 FQA:1 UA-MT1.1 Introduction:1.2 semi-supervised segmentation1.3 Uncertainty-Aware Mean Teacher Framework 参考: 0 FQA: Q1: 不确定感知是什么意思?不确定信息是啥?Q2:这篇文章的精妙的点…

Java面试——锁

​ 公平锁: 是指多个线程按照申请锁的顺序来获取锁,有点先来后到的意思。在并发环境中,每个线程在获取锁时会先查看此锁维护的队列,如果为空,或者当前线程是等待队列的第一个,就占有锁,否则就会…

idea 2018.3永久简单激活。激活码

1.打开hosts文件将 0.0.0.0 account.jetbrains.com 添加到文件末尾 C:\Windows\System32\drivers\etc\hosts 2.注册码: MNQ043JMTU-eyJsaWNlbnNlSWQiOiJNTlEwNDNKTVRVIiwibGljZW5zZWVOYW1lIjoiR1VPIEJJTiIsImFzc2lnbmVlTmFtZSI6IiIsImFzc2lnbmVlRW1haWwiOiIiLCJsaW…

数据结构知识点总结-线性表(1)-线性表的定义、基本操作、顺序表表示

线性表 定义 线性表是具有相同数据类型的N(N>0)个元素的有限序列,其中N为表长,当N0时线性表是一张空表。 线性表的逻辑特征:每个非空的线性表都有一个表头元素和表尾元素,中间的每个元素有且仅有一个直…

有趣的CSS - 弹跳的圆

大家好,我是 Just,这里是「设计师工作日常」,今天分享的是用css写一个好玩的不停弹跳变形的圆。 《有趣的css》系列最新实例通过公众号「设计师工作日常」发布。 目录 整体效果核心代码html 代码css 部分代码 完整代码如下html 页面css 样式页…

亿道丨三防平板电脑厂家丨三防平板PDA丨三防工业平板:数字时代

在当今数字化时代,我们身边的世界变得越来越依赖于智能设备和无线连接。其中,三防平板PDA(Personal Digital Assistant)作为一种功能强大且耐用的数字工具,正在引领我们进入数字世界的全新征程。 三防平板PDA结合了平板…

LeetCode 0235.二叉搜索树的最近公共祖先:用搜索树性质(不遍历全部节点)

【LetMeFly】235.二叉搜索树的最近公共祖先:用搜索树性质(不遍历全部节点) 力扣题目链接:https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/ 给定一个二叉搜索树, 找到该树中两个指定节点的最近公…

2024全国水科技大会暨减污降碳协同增效创新与实践论坛(八)

召集人:王洪臣 中国人民大学环境学院教授 姚 宏 北京交通大学教授 为大会征集“绿色低碳污水厂案例”,欢迎各相关单位积极报名! 一、会议背景 生态环境部、国家发展和改革委员会等七部门印发《减 污降碳协同增效实施方案》中明确提出推进水…

【C++】C++对C语言的关系,拓展及命名空间的使用

文章目录 📝C简述C融合了3种不同的编程方式:C和C语言关系是啥呢?C标准 🌠C应用🌠C语言优点第一个C程序 🌠命名空间🌠命名空间的使用命名空间的定义 🌠怎么使用命名空间中的内容呢&am…

测试C#使用ViewFaceCore实现图片中的人脸遮挡

基于ViewFaceCore和DlibDotNet都能实现人脸识别,准备做个遮挡图片中人脸的程序,由于暂时不清楚DlibDotNet返回的人脸尺寸与像素的转换关系,最终决定使用ViewFaceCore实现图片中的人脸遮挡。   新建Winform项目,在Nuget包管理器中…

【深度学习】微调ChatGlm3-6b

1.前言 指令微调ChatGlm3-6b。微调教程在github地址中给出,微调环境是Qwen提供的docker镜像为环境。 镜像获取方式:docker pull qwenllm/qwen:cu117 github地址:https://github.com/liucongg/ChatGLM-Finetuning 2.微调过程 github地址中的教…

Excel工作表控件实现滚动按钮效果

实例需求:工作表中有多个Button控件(工作表Form控件)和一个ScrollBar控件(工作表ActiveX控件,名称为ScrollBar2),需要实现如下图所示效果。点击ScrollBar控件实现按钮的滚动效果,实际…

2024.2.25 在centos8.0安装docker

2024.2.25 在centos8.0安装docker 安装过程比较简单,按顺序安装即可,简要步骤: 一、更新已安装的软件包: sudo yum update二、安装所需的软件包,允许 yum 通过 HTTPS 使用存储库: sudo yum install -y …

飞天使-k8s知识点22-kubernetes实操7-ingress

文章目录 ingress环境准备准备service和pod验证效果 https 代理效果 ingress 在 Kubernetes 中,Ingress 是一种 API 对象,它管理外部访问集群内部服务的规则。你可以将其视为一个入口,它可以将来自集群外部的 HTTP 和 HTTPS 路由到集群内部的…

静态时序分析:SDC约束命令set_load详解

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 set_load命令用于指定端口(port)或线网(net)的负载电容,该指令的BNF范式(有关BNF范式,可以参考以往文章)为&#…