Redis底层数据结构之IntSet

devtools/2024/9/23 4:09:58/

目录

    • 一、概述
    • 二、IntSet结构
    • 三、自动升级

上一篇 redis底层数据结构之Dict
下一篇 Redis底层数据结构之ZSkipList

一、概述

IntSet是一个存储整数值的集合,内部使用有序、无重复的数组保存数据。优点:节省内存空间。高效的查找、插入和删除操作。使用场景: 在集合键只包含整数值且数量较少时使用。

IntSet_5">二、IntSet结构

typedef struct intset {uint32_t encoding;uint32_t length;int8_t contents[];
} intset;#define INTSET_ENC_INT16 (sizeof(int16_t))
#define INTSET_ENC_INT32 (sizeof(int32_t))
#define INTSET_ENC_INT64 (sizeof(int64_t))

encoding: 数据编码,表示intset中的每个数据元素用几个字节来存储。它有三种可能的取值:INTSET_ENC_INT16表示每个元素用2个字节存储,INTSET_ENC_INT32表示每个元素用4个字节存储,INTSET_ENC_INT64表示每个元素用8个字节存储。因此,intset中存储的整数最多只能占用64bit。

length: 表示intset中的元素个数。encoding和length两个字段构成了intset的头部(header)。

contents: 是一个柔性数组(flexible array member),表示intset的header后面紧跟着数据元素。这个数组的总长度(即总字节数)等于encoding * length。柔性数组在Redis的很多数据结构的定义中都出现过(例如sds, quicklist, skiplist),用于表达一个偏移量。contents需要单独为其分配空间,这部分内存不包含在intset结构当中

在这里插入图片描述

说明:

  • 新创建的intset只有一个header,总共8个字节。其中encoding = 2, length = 0。
  • 添加13, 5两个元素之后,因为它们是比较小的整数,都能使用2个字节表示,所以encoding不变,值还是2。
  • 当添加32768的时候,它不再能用2个字节来表示了(2个字节能表达的数据范围是-215~215-1,而32768等于215,超出范围了),因此encoding必须升级到INTSET_ENC_INT32(值为4),即用4个字节表示一个元素。
  • 在添加每个元素的过程中,intset始终保持从小到大有序
  • 与ziplist类似,intset也是按小端(little endian)模式存储的(参见维基百科词条Endianness)。比如,在上图中intset添加完所有数据之后,表示encoding字段的4个字节应该解释成0x00000004,而第5个数据应该解释成0x000186A0 = 100000。

intset与ziplist相比:

  • ziplist可以存储任意二进制串,而intset只能存储整数。
  • ziplist是无序的,而intset是从小到大有序的。因此,在ziplist上查找只能遍历,而在intset上可以进行二分查找,性能更高。
  • ziplist可以对每个数据项进行不同的变长编码(每个数据项前面都有数据长度字段len),而intset只能整体使用一个统一的编码(encoding)。

三、自动升级

当在一个int16类型的整数集合中插入一个int32类型的值,整个集合的所有元素都会转换成32类型。 整个过程有三步:

  • 根据新元素的类型(比如int32),扩展整数集合底层数组的空间大小,并为新元素分配空间。
  • 将底层数组现有的所有元素都转换成与新元素相同的类型, 并将类型转换后的元素放置到正确的位上, 而且在放置元素的过程中, 需要继续维持底层数组的有序性质不变。
  • 最后改变encoding的值,length+1。

http://www.ppmy.cn/devtools/13221.html

相关文章

SQLSERVER对等发布问题处理

问题1: 无法对 数据库Sast_Business 执行 删除,因为它正用于复制。 (.Net SqlClient Data Provider) 处理: USE [master]; GO EXEC sp_replicationdboption dbname NSast_Business, optname Npublish, value Nfalse; EXEC sp_replica…

09—DOM和BOM

一、DOM 1、HTML DOM (文档对象模型) 文档对象模型(Document Object Model,DOM)是表示和操作HTML和XML文档内容的基础API。当网页被加载时,浏览器会根据DOM模型,将结构化文档(比如HTML和XML)解…

数据科学与大数据(3)

数据分析,它不应该是在一个不适合的工具下生搬硬套 工具为具体的场景服务,换一个场景大概率会很鸡肋,对于一个成熟的分析师来说,十八般武艺样样精通到后期为常态,不要产生工具上的路径依赖,不要想着学一个工…

linux负载均衡 和 系统负载分析笔记

1 负载均衡 1.1 计算负载 1.1.1 PELT算法简介 从Linux3.8内核以后进程的负载计算不仅考虑权重,⽽且跟踪每个调度实体的历史负载情况,该算法称为PELT(Per-entity Load Tracking) 《奔跑吧Linux内核》卷1:基础架构;P505 相关资料…

使用 Meta Llama 3 构建人工智能的未来

使用 Meta Llama 3 构建人工智能的未来 现在提供 8B 和 70B 预训练和指令调整版本,以支持广泛的应用 使用 Meta AI 体验 Llama 3 我们已将 Llama 3 集成到我们的智能助手 Meta AI 中,它扩展了人们完成工作、创造和与 Meta AI 联系的方式。通过使用 Meta AI 进行编码任务和解…

Win10 搭建 YOLOv8 运行环境(20240423)

一、环境要求 1、Python,版本要求>3.7 2、PyTorch,版本要求>1.7。PyTorch 是一个开源的深度学习平台,为人工智能研究提供了一个灵活的、易于使用的工具集。YOLOv8 是基于 PyTorch 框架实现的,所以需要安装 PyTorch。 3、CUD…

MT3026 砍玉米

样例1&#xff1a; 输入&#xff1a; 6 1 3 4 2 5 1 7 8 19 10 30 2 输出&#xff1a; 6 其中1<n<10^5,1<xi,hi<10^9 思路&#xff1a;贪心&#xff1a;从左到右或者从右到左依次判断每一棵玉米是否可以倒下 &#xff08;以从左到右为例&#xff1a;先往左倒&…

FreeRTOS学习 -- 任务

一、什么是任务系统 单片机裸跑的时候一般都是在main函数里面用 while (1) 做一个大循环来完成所有的处理&#xff0c;即应用程序是一个无限的循环&#xff0c;循环中调用相应的函数完成所需的处理。这个就是单任务系统&#xff0c;也称为前后台系统&#xff0c;中断服务函数作…