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组件跨页多选,已选择数据禁止第二次重复选择
需求场景:点击【新增】按钮可以在分页弹窗中跨页多选选择数据后添加到页面中,再次点击【新增】,已经选择过的数据则置灰不让重复选择。 选择后,置灰 点击【确定】数据添加到页面中,可再次点击【新增】进行添加数据 …...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
