redis底层数据结构——整数集合

server/2025/2/19 9:06:51/

文章目录

  • 定义
  • 内部实现
  • 升级
  • 升级的好处
    • 提升灵活性
    • 节约内存
  • 降级
  • 总结

定义

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

内部实现

整数集合(intset)是Redis用于保存整数值的集合抽象数据结构,它可以保存类型为 int16_t、int32_t 或者 int64_t 的整数值,并且保证集合中不会出现重复元素。

``
typedef struct intset {

//编码方式
uint32_t encoding;

//集合包含的元素数量
uint32_t length;

//保存元素的数组
int8_t contentst[] ;

} intset ;
``

  • contents数组是整数集合的底层实现:整数集合的每个元素都是contents数组的个数组项(item),各个项在数组中按值的大小从小到大有序地排列,并且数组中不包含任何重复项。
  • length属性记录了整数集合包含的元素数量,也即是contents数组的长度。
  • encoding实际编码。

升级

每当我们要将一个新元素添加到整数集合里面,并且新元素的类型比整数集合现有所有元素的类型都要长时,整数集合需要先进行升级(upgrade),然后才能将新元素添加到整数集合里面。

升级整数集合并添加新元素共分为三步进行:

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

因为每次向整数集合添加新元素都可能会引起升级,而每次升级都需要对底层数组中已有的所有元素进行类型转换,所以向整数集合添加新元素的时间复杂度为O(M)。

升级的好处

整数集合的升级策略有两个好处,一个是提升整数集合的灵活性,另一个是尽可能地节约内存。

提升灵活性

因为C语言是静态类型语言,为了避免类型错误,我们通常不会将两种不同类型的值放在同一个数据结构里面。

但是,因为整数集合可以通过自动升级底层数组来适应新元素,所以我们可以随意地将 int16t、int32t或者int64t类型的整数添加到集合中,而不必担心出现类型错误这种做法非常灵活。

节约内存

当然,要让一个数组可以同时保存int16_t、int32_t、int64_t三种类型的值,最简单的做法就是直接使用int64_t类型的数组作为整数集合的底层实现。不过这样一来,即便添加到整数集合里面的都是int16_t类型或者int32.t类型的值,数组都需要使用int64t类型的空间去保存它们,从而出现浪费内存的情况。

而整数集合现在的做法既可以让集合能同时保存三种不同类型的值,又可以确保升级操作只会在有需要的时候进行,这可以尽量节省内存。

降级

整数集合不支持降级操作,一且对数组进行了升级,编码就会一直保持升级后的状态。 这点比较特别,因为大多数的场景都是有升级就有降级。不做降级的考虑是实现方便,无需考虑频繁进行升级降级的变化。

总结

  • 整数集合是集合键的底层实现之一
  • 整数集合的底层实现为数组,这个数组以有序、无重复的方式保存集合元素,在有需要时,程序会根据新添加元素的类型,改变这个数组的类型。
  • 升级操作为整数集合带来了操作上的灵活性,并且尽可能地节约了内存。整数集合只支持升级操作,不支持降级操作。

http://www.ppmy.cn/server/167550.html

相关文章

【杨辉三角形——找规律,二分】

题目 代码 #include <bits/stdc.h> using namespace std; using ll long long; int n;ll C(int a, int b) {ll retv 1;for(int i a, j 1; j < b; i--, j){retv retv * i / j;if(retv > n)return retv;}return retv; } bool check(int k) {int l 2 * k, r m…

【Unity Shader编程】之GPU编程前言

之前一直不懂&#xff0c;为什么写一个shader代码&#xff0c;然后整个模型就会动&#xff0c;因为之前都是cpu编程思路&#xff0c;比如说cpu控制一个人物行走&#xff0c;就是控制一个人物&#xff0c;要控制10个人物&#xff0c;就要循环10次&#xff0c;分别控制他们&#…

《漫威蜘蛛侠2》,双主角模式下的全新挑战

近日&#xff0c;特备受玩家期待的《漫威蜘蛛侠2》正式登录PC平台&#xff0c;作为PlayStation又一3A大作&#xff0c;首发PS5平台的优异表现可谓是赚足了眼球。而且在大作云集的2025年&#xff0c;《漫威蜘蛛侠2》强势登陆PC端&#xff0c;可以说让无数非主机党玩家兴奋不已 …

DeepSeekV3报告及代码解读

DeepSeekV3报告及代码解读 DONGYONGFEI786 20250210 目录 1. 架构创新 1.1 DeepSeekMoE with auxiliary-loss-free strategy 1.2 Multi-head Latent Attention (MLA) 1.3 Multi-Token Prediction (MTP) 2. 训练效率优化 2.1 DualPipe流水线并行算法 2.2 FP8混合精度训练框架…

系统思考—团队学习

“一个人的成长是从问题中学习&#xff0c;而组织的成长是从结构中进化。” —— 彼得圣吉 看似松散的团队学习结构&#xff0c;回头一看&#xff0c;你早已成长了许多。今天和小伙伴们聊起2024年&#xff0c;才发现很多改变&#xff0c;都是在不经意间发生的。 从最初的探索…

微信小程序登陆鉴权最佳实现

文章目录 一、使用步骤1.创建鉴权组件auth2.app.json中注册全局组件3.页面使用组件4. 读取本地存储的 token 数据&#xff0c;用于判断是否曾登录过5. 检测登录状态&#xff0c;要求未登录时不显示页面中的内容且跳转到登录页面 一、使用步骤 1.创建鉴权组件auth 2.app.json中…

JUnit 4与JUnit 5的差异详解

概述 在进行SpringBoot项目单元测试时&#xff0c;发现有时候给类打上 SpringBootTest注解就能运行项目&#xff0c;但有时候需要RunWith(SpringRunner.class)和SpringBootTest注解才能运行&#xff0c;你有研究过这是为什么吗&#xff1f;本文就来讲一下这个问题。 Spring Bo…

Python自动化办公之Excel拆分

在日常办公中&#xff0c;我们经常需要将包含多个Sheet页的Excel文件拆分成多个独立的Excel文件。例如&#xff0c;当我们要把一份Excel表格发给各部门确认时&#xff0c;出于控制信息知悉范围、确保数据保密性等方面的考虑&#xff0c;每个部门仅需查看和确认与自己部门对应的…