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

文章目录

定义

整数集合(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类型的空间去保存它们,从而出现浪费内存的情况。

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

降级

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

总结

  • 整数集合是集合键的底层实现之一
  • 整数集合的底层实现为数组,这个数组以有序、无重复的方式保存集合元素,在有需要时,程序会根据新添加元素的类型,改变这个数组的类型。
  • 升级操作为整数集合带来了操作上的灵活性,并且尽可能地节约了内存。整数集合只支持升级操作,不支持降级操作。
相关推荐
yanchao_hu31 分钟前
数据结构基础内容(第二篇:线性结构)
数据结构·windows
拳里剑气1 小时前
C语言:顺序表(上)
c语言·开发语言·数据结构·学习方法
积极向上的zzz2 小时前
java中一些数据结构的转换
java·开发语言·数据结构
卓航2 小时前
Redis slowlog使用和实现
redis
每天都在想吃啥3 小时前
day22 哈希表和二叉树
数据结构·哈希算法·散列表
波吉爱睡觉3 小时前
Redis反弹Shell
redis·web安全·网络安全
Das13 小时前
【初识数据结构】CS61B 中的归并排序和选择排序
数据结构·算法·排序算法
骑着蜗牛闯宇宙4 小时前
Thinkphp8 Redis队列与消息队列Queue
redis·php
是阿建吖!6 小时前
【Redis】初识Redis(定义、特征、使用场景)
数据库·redis·缓存
yanchao_hu6 小时前
数据结构基本内容(第四篇:队列)
数据结构