15- Redis 中的 整数集合 数据结构

news2024/12/30 1:15:36

整数集合是 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;

不同类型的 contents 数组,意味着数组的大小也会不同。

2. 整数集合的升级操作

整数集合会有一个升级规则,就是当我们将一个新元素加入到整数集合里面,如果新元素的类型(int32_t)比整数集合现有所有元素的类型(int16_t)都要长时,整数集合需要先进行升级,也就是按新元素的类型(int32_t)扩展 contents 数组的空间大小,然后才能将新元素加入到整数集合里,当然升级的过程中,也要维持整数集合的有序性。

为什么管理混合类型会增加复杂度:

从计算机的基本原理来看,int16_tint32_t 在内存中的占用大小、表达范围以及在某些情况下的处理方式上存在区别,这些区别导致了在处理它们时的一些差异。在数据结构内部同时管理 int16_tint32_t 类型的数据,意味着每次操作数据(如添加、删除、查找)时,都需要判断并根据不同的类型作相应处理。这不仅在编码时增加了分支判断的复杂度,还可能导致在执行时增加额外的判断开销。此外,混合类型的数据存储可能导致内存布局的非连续性和对齐问题,进而影响访问效率。

因此,虽然 int16_tint32_t 在概念上是相似的(都是用来存储整数的类型),但它们在内存占用、表达范围和处理细节上的这些区别,决定了在统一的数据结构中同时管理这些不同类型会使得结构管理变得更加复杂。Redis 的整数集合通过类型升级来避免这种复杂性,从而使得数据存储、访问和维护更加高效和一致。

整数集合升级的过程不会重新分配一个新类型的数组,而是在原本的数组上扩展空间,然后再将每个元素按间隔类型大小分割,如果 encoding 属性值为 INTSET_ENC_INT16,则每个元素的间隔就是 16 位。

举个例子,假设有一个整数集合里有 3 个类型为 int16_t 的元素。

现在,往这个整数集合中加入一个新元素 65535,这个新元素需要用 int32_t 类型来保存,所以整数集合要进行升级操作,首先需要为 contents 数组扩容,在原本空间的大小上再扩容多 80 位(4 × 32 - 3 × 16 = 80),这样就能保存下四个类型为 int32_t 的元素

扩容完 contents 数组空间大小后,需要将之前的三个元素转换为 int32_t 类型,并将转换后的元素放置到正确的位上面,并且需要维持底层数组的有序性不变,整个转换过程如下:

整数集合升级有什么好处呢?

如果要让一个数组同时保存 int16_t、int32_t、int64_t 类型的元素,最简单的做法就是直接使用 int64_t 类型的数组。不过这样的话,当如果元素都是 int16_t 类型的,就会造成内存浪费的情况。

整数集合升级就能避免这种情况,如果一直向整数集合添加 int16_t 类型的元素,那么整数集合的底层实现就一直是用 int16_t 类型的数组,只有在我们要将 int32_t 类型或 int64_t 类型的元素添加到集合时,才会对数组进行升级操作。

因此,整数集合升级的好处是节省内存资源

整数集合支持降级操作吗?

不支持降级操作,一旦对数组进行了升级,就会一直保持升级后的状态。比如前面的升级操作的例子,如果删除了 65535 元素,整数集合的数组还是 int32_t 类型的,并不会因此降级为 int16_t 类型。

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

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

相关文章

​在 The Sandbox 元宇宙的 CU 超商中寻找Milk币!

CU(韩国领先的便利店)和 MiL.k(基于区块链的忠诚度整合平台)合作在 The Sandbox 推出了首款元宇宙游戏,通过独家活动在 Web2 和 Web3 之间建立联系。 在元宇宙中玩转 “Play CU X MiL.k” 体验 通过引人入胜的游戏内容…

uniapp小程序多线程 Worker 实战【2024】

需求 最近遇到个小程序异步解码的需求,采用了WebAssembly,涉及大量的计算。由于小程序的双线程模型只有一个线程处理数据,因此智能寻求其它的解决方案。查看小程序的文档,发现小程序还提供一个异步线程的Worker方案,可…

暗黑系短视频:成都鼎茂宏升文化传媒公司

暗黑系短视频:探索未知的视觉艺术 在短视频盛行的今天,各种风格和主题的作品层出不穷,其中,暗黑系短视频以其独特的魅力和深度,成都鼎茂宏升文化传媒公司吸引了众多观众的关注。这类视频往往带有一种神秘、压抑的氛围…

李良济中医课堂,助力市民健康,传播中医药文化,坚守初心扬国粹!

为了更好地传承并发扬中医文化,传播健康理念,提高民众预防疾病的意识,让广大市民感受到中医药就在我身边。 李良济中医课堂,积极走进老年大学,青年夜校,同时主动加入萌趣中草药的活动等,为市民群…

小程序集arcgis地图显示自定义坐标的功能实现记录!(学习笔记)

最近再做一个新能源回收项目,项目中有个根据回收点坐标数据显示区域内回收点位置,点击图标直接导航到该位置,及分布的需求,研究了一下,实现效果如下,实现起来很简单,代码及效果 回收点位置及分…

在编程Python的时候发生ModuleNotFoundError: No module named distutils报错怎么办

1.先查看Python版本 首先我们先去打开终端就是先widr再输入cmd 然后进去在输入Python -V要注意大小写 我的版本是3.9.7版本但是我使用的PyCharm 是 2021.1.1 x64版本没有办法主动去识别因为这个版太低了你的Python版本很高所以无法识别 2.解决方法 只需要把你的Python现版…

使用手机小程序给证件照换底色

临时遇到一个需求,需要给证件照换底色。原始图像如下 最终需要换成红底的。 本次使用一款小程序"泰世茂证件照",打开该小程序,如下图所示 单击开始制作,然后选择二寸红底,如下图所示 然后单击相…

UI 自动化中的分层设计

以前的设计 在过去 UI 自动化测试领域有一个规范的设计模式是 page object 模式。 意思是测试用例不会直接定位页面元素, 而是把每一个页面封装成一个类。 在这个类中封装页面元素。 然后测试用例调用 page 类来操作页面元素完成测试用例。如下图: 以前…

前端面试题(二)答案版

面试形式:线上面试(不露脸):时长40分钟 面试评价:由易到难,由细到全,比较不错 面试官:项目经理 面试官提问(面试题): 1、聊聊最近写的这个项目…

【Meetup】探索Apache SeaTunnel的二次开发与实战案例

在数据科技快速演进的今天,业务场景的复杂化和数据量的激增,推动了大数据技术的迅速发展,在众多开源大数据处理工具中,Apache SeaTunnel以其强大的数据集成能力,成为众多企业的首选。 但随着应用深入,企业面…

32个小众搜索网站,相信一定有你想要的

首先问你一个问题,你平时都会用什么搜索引擎来进行搜索? 下面我将推荐32个小众搜索网站,相信一定会有你想要的。 1、多吉搜索 首先对因为拒绝商业化黑客攻击、不可抗力而停止服务的多吉搜索表示哀悼,这款由个人开发的小众搜索引…

Flutter基础 -- Flutter布局练习(小项目)

目录 1. Splash 布局(第一页) 1.1 目标 1.2 当前效果图 1.3 创建 Splash 界面 1.4 设置 MaterialApp 1.5 设置 Splash 背景色 1.6 布局 Splash 界面 1.7 总结 2. Splash 圆角图片 2.1 目标 2.2 当前效果图 2.3 蓝湖下载图片 2.4 图片导入项…

QT 信号和槽 一对多关联示例,一个信号,多个槽函数响应,一个信号源如何绑定多个槽函数

在窗体里放置一个单行文本编辑控件(QLineEdit)、一个标签控件(QLabel)和一个文本浏览控件(QTextBrowser),在单行文 本编辑控件里的文本被编辑时,标签控件和文本浏览控件都会同步显示…

OpenMV学习笔记4——二维码识别

一、示例程序 按照下图顺序点击,即可打开官方在IDE中准备好的二维码实例程序: # QRCode Example # # This example shows the power of the OpenMV Cam to detect QR Codes # using lens correction (see the qrcodes_with_lens_corr.py script for hig…

【Vue】项目目录介绍和运行流程

文章目录 一、项目目录介绍二、public/index.html三、src/main.js四、运行流程 一、项目目录介绍 虽然脚手架中的文件有很多,目前咱们只需认识三个文件即可,这三个文件就决定了我们项目的运行 main.js 入口文件App.vue App根组件index.html 模板文件 我…

如何实现vue项目不同屏幕适配(2024最新)

文章目录 1.下载插件,修改px单位为rem单位2.配置vue.config.js(如下图位置所示)3.屏幕自适应4.项目实际使用 1.下载插件,修改px单位为rem单位 npm i postcss-plugin-px2rem2.配置vue.config.js(如下图位置所示) 注意在根目录下,如果没有该文…

【记录贴:分布式系列文章】

分布式系列文章目录 文章目录 分布式系列文章目录前言一、Redisq1.怎么判断是否命中缓存1. MySQL数据库如何检查询查缓存是否命中链接2.如何判断redis是否命中缓存链接 q2.Redis缓存穿透、雪崩、击穿以及分布式锁和本地锁 二、分布式q1.分布式订单号生成策略q2.接口幂等性,防止…

Crosslink-NX器件应用连载(9): USB3.0相机

作者:Hello,Panda 大家晚上好,很久没有分享设计案例了,实在是太忙了,精力十分有限,今天分享一个CrosslinkNX系列器件用作USB3.0相机的案例。其实就是分享一下使用CrosslinkNX器件设计USB3.0相机主要有两种…

腾讯云 TDMQ for Apache Pulsar 多地区高可用容灾实践

作者介绍 林宇强 腾讯云高级工程师 专注于消息队列、API网关、微服务、数据同步等 PaaS 领域。有多年的开发和维护经验,目前在腾讯云从事 TDMQ Pulsar 商业化产品方向的研发工作。 导语 本文将从四个维度,深入剖析 Pulsar 在多可用区高可用领域的容…

C++ 并发编程指南(5)线程状态及切换

文章目录 一、多线程状态及切换1、线程状态2、状态切换 前言&#xff1a; C中的线程状态及切换是操作系统和C线程库&#xff08;如POSIX线程或C11及之后的<thread>库&#xff09;共同管理的。线程的状态和切换是多线程编程中的重要概念&#xff0c;下面将简要介绍C线程的…