6、Redis系统-数据结构-05-整数
五、整数集合(Intset)
整数集合是 Redis 中 Set 对象的底层实现之一。当一个 Set 对象只包含整数值元素,并且元素数量不大时,就会使用整数集合这个数据结构作为底层实现。整数集合通过紧凑的内存布局和升级机制,实现了高效的整数存储和操作。
1. 结构设计
整数集合本质上是一块连续的内存空间,其结构定义如下:
typedef struct intset {// 编码方式uint32_t encoding;// 集合包含的元素数量uint32_t length;// 保存元素的数组int8_t contents[];
} intset;
可以看到,保存元素的容器是一个 contents 数组,虽然 contents 被声明为 int8_t 类型的数组,但是实际上 contents 数组并不保存任何 int8_t 类型的元素,contents 数组的真正类型取决于 intset 结构体里的 encoding 属性的值。比如:
- 如果
encoding属性值为INTSET_ENC_INT16,那么contents就是一个int16_t类型的数组,数组中每一个元素的类型都是int16_t。 - 如果
encoding属性值为INTSET_ENC_INT32,那么contents就是一个int32_t类型的数组,数组中每一个元素的类型都是int32_t。 - 如果
encoding属性值为INTSET_ENC_INT64,那么contents就是一个int64_t类型的数组,数组中每一个元素的类型都是int64_t。
2. 升级操作
整数集合的一个重要特性是支持升级操作。当将一个新元素加入到整数集合中,如果新元素的类型(例如 int32_t)比集合中现有所有元素的类型(例如 int16_t)都要长时,整数集合需要先进行升级操作。升级操作包括扩展 contents 数组的空间大小和维持集合的有序性。
升级示例
假设一个整数集合包含三个 int16_t 类型的元素:
contents: [1, 2, 3] // 类型:int16_t
现在,我们将一个新元素 65535 加入到集合中,由于这个新元素需要用 int32_t 类型来保存,因此需要进行升级操作:
-
扩展空间:首先需要为
contents数组扩容,在原本空间的大小之上再扩容多 80 位(4x32 - 3x16 = 80),这样就能保存下 4 个int32_t类型的元素。 -
转换类型:扩容完
contents数组空间大小后,需要将之前的三个int16_t类型的元素转换为int32_t类型,并将转换后的元素放置到正确的位置上,并且需要维持底层数组的有序性不变。
升级后的 contents 数组如下:
contents: [1, 2, 3, 65535] // 类型:int32_t
升级的好处
- 节省内存:如果直接使用
int64_t类型的数组来保存所有元素,虽然可以保存不同类型的整数,但会造成内存浪费。例如,当元素都是int16_t类型时,使用int64_t类型数组会浪费大量内存。 - 灵活性:通过升级机制,整数集合可以根据需要动态调整数组类型,既能节省内存,又能支持更大范围的整数。
不支持降级
值得注意的是,整数集合不支持降级操作。一旦数组类型升级到更大的整数类型,就不会再降级回较小的类型。这是为了简化实现和避免降级过程中可能产生的复杂性。
3. 操作实现
整数集合支持多种操作,包括插入、删除、查找等。以下是一些常见操作的实现示例:
插入操作
插入新元素时,首先检查新元素的类型是否需要升级。如果需要升级,先进行升级操作,然后将新元素插入到正确的位置,维持数组的有序性。
intset *intsetAdd(intset *is, int64_t value, uint8_t *success) {uint8_t valenc = _intsetValueEncoding(value);uint32_t pos;if (success) *success = 1;if (valenc > intrev32ifbe(is->encoding)) {// 升级操作return intsetUpgradeAndAdd(is, value);} else {if (intsetSearch(is, value, &pos)) {if (success) *success = 0;return is;}// 插入操作is = intsetResize(is, intrev32ifbe(is->length) + 1);if (pos < intrev32ifbe(is->length)) {memmove(intsetGet(is, pos + 1), intsetGet(is, pos),(intrev32ifbe(is->length) - pos) * intrev32ifbe(is->encoding));}intsetSet(is, pos, value);is->length = intrev32ifbe(intrev32ifbe(is->length) + 1);}return is;
}
查找操作
查找元素时,通过二分查找算法在有序数组中高效地查找目标元素的位置。
uint8_t intsetSearch(const intset *is, int64_t value, uint32_t *pos) {int64_t cur;int min = 0, max = intrev32ifbe(is->length) - 1, mid = -1;if (intrev32ifbe(is->length) == 0) {if (pos) *pos = 0;return 0;} else {while (max >= min) {mid = (min + max) >> 1;cur = intsetGet(is, mid);if (value > cur) {min = mid + 1;} else if (value < cur) {max = mid - 1;} else {break;}}if (value == cur) {if (pos) *pos = mid;return 1;} else {if (pos) *pos = min;return 0;}}
}
删除操作
删除元素时,首先查找到目标元素的位置,然后移除该元素并调整数组大小。
intset *intsetRemove(intset *is, int64_t value, int *success) {uint8_t valenc = _intsetValueEncoding(value);uint32_t pos;if (success) *success = 0;if (valenc <= intrev32ifbe(is->encoding) && intsetSearch(is, value, &pos)) {uint32_t len = intrev32ifbe(is->length);// 移除操作if (pos < (len - 1)) {memmove(intsetGet(is, pos), intsetGet(is, pos + 1),(len - pos - 1) * intrev32ifbe(is->encoding));}is = intsetResize(is, len - 1);is->length = intrev32ifbe(len - 1);if (success) *success = 1;}return is;
}
4. 使用示例
以下是一些使用 Redis 整数集合的示例,展示了如何利用整数集合进行数据的存储和操作。
插入数据
SADD myset 1
SADD myset 2
SADD myset 3
获取数据
SMEMBERS myset
# 1) "1"
# 2) "2"
# 3) "3"
删除数据
SREM myset 2
SMEMBERS myset
# 1) "1"
# 2) "3"
结论
通过上述解析,我们可以更好地理解整数集合的设计思想和实现原理,从而在实际开发中更好地利用整数集合提供的优势。在 Redis 中,整数集合通过紧凑的内存布局和动态升级机制,实现了高效的整数存储和操作。了解这些优化策略,可以帮助我们在实际应用中更好地利用 Redis 的性能和功能。
相关文章:
6、Redis系统-数据结构-05-整数
五、整数集合(Intset) 整数集合是 Redis 中 Set 对象的底层实现之一。当一个 Set 对象只包含整数值元素,并且元素数量不大时,就会使用整数集合这个数据结构作为底层实现。整数集合通过紧凑的内存布局和升级机制,实现了…...
STM32学习历程(day5)
EXTI外部中断 中断 中断就是在主程序运行过程中 出现了特定的中断触发条件(中断源),CPU会暂停当前的程序,去处理中断程序 处理完会返回被暂停的位置 继续运行原来的程序。 中断优先级 当有多个中断源同时申请中断时 CPU会根据…...
格蠹汇编阅读理解
一、调试工具使用方式 WinDbg常用命令: 执行 lm 命令,可以看到进程中有几个模块。执行~命令列一下线程。用!heap 命令列一下堆。执行!address 命令可以列出用户态空间中的所有区域。搜索吧!就从当前进程用户态空间的较低地址开始搜…...
深入探索:scikit-learn中递归特征消除(RFE)的奥秘
深入探索:scikit-learn中递归特征消除(RFE)的奥秘 在机器学习的世界里,特征选择是一项至关重要的任务。它不仅能够提高模型的性能,还能减少模型的复杂度,避免过拟合。scikit-learn,作为Python中一个广泛使用的机器学习…...
240708_昇思学习打卡-Day20-MindNLP ChatGLM-6B StreamChat
240708_昇思学习打卡-Day20-MindNLP ChatGLM-6B StreamChat 基于MindNLP和ChatGLM-6B实现一个聊天应用,本文进行简单记录。 环境配置 %%capture captured_output # 实验环境已经预装了mindspore2.2.14,如需更换mindspore版本,可更改下面mi…...
lua入门(2) - 数据类型
前言 本文参考自: Lua 数据类型 | 菜鸟教程 (runoob.com) 希望详细了解的小伙伴还请查看上方链接: 八个基本类型 type - 函数查看数据类型: 测试程序: print(type("Hello world")) --> string print(type(10.4*3)) --> number print(t…...
dify/api/models/provider.py文件中的数据表
源码位置:dify/api/models/provider.py providers 表结构 字段英文名数据类型字段中文名字备注idStringUUIDIDtenant_idStringUUID租户IDprovider_nameString提供商名称provider_typeString提供商类型encrypted_configText加密配置is_validBoolean是否有效last_us…...
从入门到精通:网络基础详解
前言 在现代社会,网络技术已经成为我们日常生活和工作中不可或缺的一部分。从简单的网页浏览到复杂的分布式系统,网络技术都扮演着至关重要的角色。通过这篇文章,读者将从入门到精通,全面掌握网络编程的理论和实践。 重点摘要 …...
初步理解三__《面向互联网大数据的威胁情报 并行挖掘技术研究》
初步理解三 5类战术标签 gtp 收集开源的网络安全报告并将其转化为统一的文本格式,并且标注了5类战术标签是一个涉及到数据处理和分类的复杂任务。以下是一种可能的处理方法: 数据收集和整合: 使用网络爬虫或API访问工具收集开源的网络安全…...
【C++修行之道】string类的使用
目录 一.C语言中的字符串 二、标准库中的string类 (了解) 2.1 string类(了解) 2.2 帮助文档阅读 三、 string类的常用接口说明 3.1 string类对象的常见构造 3.2 string类对象的容量操作 3.3 string类对象的访问及遍历操作 字符串类的简单实现 3.4 string类对象的修改…...
云原生监控-Kubernetes-Promethues-Grafana
云原生监控-Prometheus 作者:行癫(盗版必究) 引读:本文章所涉及到技术点包括Prometheus、Grafana、Kuebrnetes;Prometheus基于外部构建采集并监控Kubernetes集群以及集群中的应用,例如使用mysql-node-exporter、nginx-node-exporter采集Kuebrnetes集群中的应用数据,使用…...
MySQL高级----InnoDB引擎
逻辑存储结构 表空间 表空间(ibd文件),一个mysql实例可以对应多个表空间,用于存储记录、索引等数据。 段 段,分为数据段(Leaf node segment)、索引段(Non-leaf node segment)、回滚段(Rollback segment),InnoDB是…...
Docker定时清理
一、循环调度执行 1、检查cron状态 systemctl status crond 2、创建要执行的shell脚本 vim /home/cleanup_docker.sh #! /bin/bash # 清理临时文件 echo $(date "%H:%M:%S") "执行docker清理命令..." docker system prune -af-a 清理包括未使用的镜像 …...
mysql之导入测试数据
运维时经常要这样:mysql改表名,创建一个一样的表不含数据,复制旧表几条数据进去 改变表的名字: RENAME TABLE old_table_name TO new_table_name; 这将把原来的表old_table_name重命名为new_table_name。 创建一个一样的表结构…...
WPScan漏洞扫描工具的介绍及使用
目录 1. 介绍2. 常用参数 1. 介绍 WPScan是Kali Linux默认自带的一款漏洞扫描工具,它采用Ruby编写,能够扫描WordPress网站中的多种安全漏洞,其中包括WordPress本身的漏洞、插件漏洞和主题漏洞,最新版本WPScan的数据库中包含超过18…...
基于单片机的饲料搅拌机控制系统设计
摘要 : 文章主要从软件和硬件两个部分对基于单片机的饲料搅拌机控制系统进行研究设计 。 硬件部分主要由传感器模块 、 信号采集模块、 键盘接入模块 、 LED 显示模块 、 继电器模块以及看门狗模块组成 。 软件部分在 KeilC51 软件基础上重点对控制系统主程序 、…...
Mysql笔记-v2
零、 help、\h、? 调出帮助 mysql> \hFor information about MySQL products and services, visit:http://www.mysql.com/ For developer information, including the MySQL Reference Manual, visit:http://dev.mysql.com/ To buy MySQL Enterprise support, training, …...
Java SpringBoot MongoPlus 使用MyBatisPlus的方式,优雅的操作MongoDB
Java SpringBoot MongoPlus 使用MyBatisPlus的方式,优雅的操作MongoDB 介绍特性安装新建SpringBoot工程引入依赖配置文件 使用新建实体类创建Service测试类进行测试新增方法查询方法 官方网站获取本项目案例代码 介绍 Mongo-Plus(简称 MP)是一…...
【易捷海购-注册安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…...
antd+vue——实现table组件跨页多选,已选择数据禁止第二次重复选择
需求场景:点击【新增】按钮可以在分页弹窗中跨页多选选择数据后添加到页面中,再次点击【新增】,已经选择过的数据则置灰不让重复选择。 选择后,置灰 点击【确定】数据添加到页面中,可再次点击【新增】进行添加数据 …...
5步释放Win11潜能:用Win11Debloat让系统性能提升60%的实战指南
5步释放Win11潜能:用Win11Debloat让系统性能提升60%的实战指南 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutte…...
抖音批量下载终极指南:一键获取无水印视频与创作者全部作品
抖音批量下载终极指南:一键获取无水印视频与创作者全部作品 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback …...
临床数据建模实战:Lasso回归在蛋白质组学中的5个关键应用技巧
临床数据建模实战:Lasso回归在蛋白质组学中的5个关键应用技巧 蛋白质组学数据的高维度特性让传统统计方法束手无策——当检测指标数量达到数千甚至上万时,如何从海量蛋白质中识别出真正有临床意义的生物标志物?这正是Lasso回归大显身手的领域…...
多宽带联网(五) OpenWrt中MWAN3高级策略分流实战(游戏加速、视频优化场景)
1. MWAN3策略分流的核心价值 家里拉了两条宽带却发现刷视频卡、打游戏延迟高?这种情况我遇到过太多次了。去年给朋友家调试网络时,他同时接了电信和联通两条200M宽带,但看4K视频还是缓冲,玩外服游戏延迟总在200ms以上。后来用Open…...
如何用Obsidian Image Converter实现图像高效管理?超实用技巧分享
如何用Obsidian Image Converter实现图像高效管理?超实用技巧分享 【免费下载链接】obsidian-image-converter ⚡️ Convert, compress, resize, annotate, markup, draw, crop, rotate, flip, align images directly in Obsidian. Drag-resize, rename with variab…...
别只盯着协议!用TC8测试案例深度解读车载网络中的ARP与ICMP:安全与稳定的隐藏关卡
车载以太网底层协议实战:从TC8测试案例看ARP与ICMP的安全设计 当一辆现代汽车以100km/h行驶时,其车载网络每秒需要处理超过5000条网络报文。这些报文中的绝大多数,都由ARP和ICMP这样的基础协议承载。在传统IT领域被视为"简单"的协议…...
如何在3分钟内为你的项目生成真实可信的测试姓名数据?
如何在3分钟内为你的项目生成真实可信的测试姓名数据? 【免费下载链接】uinames A simple tool to generate names for use in designs and mockups. 项目地址: https://gitcode.com/gh_mirrors/ui/uinames 你是否曾经为测试数据而烦恼?在开发用户…...
原创:第三篇(工程落地・首个抓手)电磁筑基:无线充电工程落地总案
第三篇(工程落地・首个抓手)电磁筑基:无线充电工程落地总案 作者:华夏之光永存 总摘要 当前人类电磁学应用仍处于婴孩阶段,现有电磁能量传输技术多局限于有线模式,存在传输损耗高、场景适配性差、灵活性不足…...
AI大模型时代:微店商品数据API如何重构反向海淘决策
在AI大模型时代,微店商品数据API凭借覆盖下沉市场、小众货源、私域供给的独特优势,成为重构反向海淘决策的核心支撑,将传统“人工经验判断”升级为“数据采集→AI分析→自动决策→反馈优化”的全链路数据驱动模式,大幅提升选品精准…...
Python: 多优化算法TSP求解方案,物流路径规划代码实践 - 附详尽注释及标准数据集
Python:模拟退火算法、蚁群算法、遗传算法、粒子群算法求解旅行商问题(TSP)的Python代码程序。 物流路径规划问题。 -- 数据集采用的tsplib标准数据集,可以根据自己需求修改城市坐标。 代码完整,注释详细,打印每次迭代结果&#x…...
