Redis原理再学习05:数据结构-整数集合intset
intset介绍
intset 整数集合,当一个集合只有整数元素,且元素数量不多时,Redis 就会用整数集合作为集合键的底层实现。
redis> SADD numbers 1 3 5 7 9
(integer 5)
redis> OBJECT ENCODING numbers
(inset)
为什么要用 intset?
集合键的另外一种实现是值为空的散列表(hash table),当元素比较少时,用hash table 存就比较浪费内存,而用
intset 就比较节约内存。
整数集合实现
intset 结构定义:
// https://github.com/redis/redis/blob/3.0/src/intset.h#L35
typedef struct intset {
uint32_t encoding; // 编码格式, 这个格式有3种,见下面
uint32_t length; // 集合元素的数量
int8_t contents[]; // 保存元素的数组
} intset;
// https://github.com/redis/redis/blob/3.0/src/intset.c#L40
/* Note that these encodings are ordered, so:
* INTSET_ENC_INT16 < INTSET_ENC_INT32 < INTSET_ENC_INT64. */
#define INTSET_ENC_INT16 (sizeof(int16_t)) // 16位2个字节
#define INTSET_ENC_INT32 (sizeof(int32_t)) // 32位4个字节
#define INTSET_ENC_INT64 (sizeof(int64_t)) // 64位8个字节
intset 整数集合结构示意图:

虽然,intset 整数集合里字段 contents 声明是 int8_t 数据类型,但是 contents 存储的数据类型是根据 encoding 属性值来确定的。
- encoding 值为 INTSET_ENC_INT16 时,contents 就是一个 int16_t 类型的数组,数组里每一项都是 int16_t 类型的整数值。最小值为 -32768,最大值为 32767。
- 同理,encoding 值为 INTSET_ENC_INT32 时,contents 就是一个 int32_t 类型的数组,数组里每一项都是 int32_t 类型的整数值。最小值为 -2,147,483,648,最大值为 2,147,483,647。
- 同理,encoding 值为 INTSET_ENC_INT64 时,contents 就是一个 int64_t 类型的数组,数组里每一项都是 int64_t 类型的整数值。最小值为 -9,223,372,036,854,775,808,最大值为 9,223,372,036,854,775,807。
encoding 的值为什么有 3 种呢?
为了节省内存。redis 可以根据存储的元素数值大小,选择合适的类型来存储。
比如添加新元素时,元素整数值超过了当前编码格式能表示的范围,就升级数据类型。
整数集合操作的一些 API
整数集合操作一些 API:
// https://github.com/redis/redis/blob/3.0/src/intset.h#L41
intset *intsetNew(void); // 创建空集合
intset *intsetAdd(intset *is, int64_t value, uint8_t *success); // 将 value 添加到 is 集合中
intset *intsetRemove(intset *is, int64_t value, int *success); // 将 value 从 is 集合中移除
uint8_t intsetFind(intset *is, int64_t value); // 在结合 is 中搜索 value 元素,成功返回1,失败返回0
int64_t intsetRandom(intset *is); // 随机返回一个元素
uint8_t intsetGet(intset *is, uint32_t pos, int64_t *value); // 获取下标为pos的元素值并保持在value中
uint32_t intsetLen(intset *is); // 计算集合中元素个数
size_t intsetBlobLen(intset *is); // 计算集合中元素所占字节总数
获取元素编码格式函数:
// https://github.com/redis/redis/blob/3.0/src/intset.c#L45
/* Return the required encoding for the provided value. */
static uint8_t _intsetValueEncoding(int64_t v) {
if (v < INT32_MIN || v > INT32_MAX)
return INTSET_ENC_INT64;
else if (v < INT16_MIN || v > INT16_MAX)
return INTSET_ENC_INT32;
else
return INTSET_ENC_INT16;
}
参考
Redis原理再学习05:数据结构-整数集合intset的更多相关文章
- redis 底层数据结构 整数集合intset
整数集合是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时Redis就会使用整数集合作为集合键的底层实现 整数集合是Redis用于保存整数值的集合抽象数据结构,它可以保存 ...
- Redis原理再学习04:数据结构-哈希表hash表(dict字典)
哈希函数简介 哈希函数(hash function),又叫散列函数,哈希算法.散列函数把数据"压缩"成摘要,有的也叫"指纹",它使数据量变小且数据格式大小也固定 ...
- Redis数据结构—整数集合与压缩列表
目录 Redis数据结构-整数集合与压缩列表 整数集合的实现 整数集合的升级 整数集合不支持降级 压缩列表的构成 压缩列表节点的构成 小结 Redis数据结构-整数集合与压缩列表 大家好,我是白泽.今 ...
- Redis数据结构之整数集合-intset
当一个集合只包含整数值元素,并且这个集合的元素数量不多时,Redis会使用整数集合(intset)来存储集合元素. intset是紧凑的数组结构,同时支持16位.32位和64位整数. 结构 struc ...
- 学习javascript数据结构(三)——集合
前言 总括: 本文讲解了数据结构中的[集合]概念,并使用javascript实现了集合. 原文博客地址:学习javascript数据结构(三)--集合 知乎专栏&&简书专题:前端进击者 ...
- Redis源码解析:06整数集合
整数集合(intset)是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时,Redis就会使用整数集合作为集合键的底层实现. intset可以保存类型为int16_t,i ...
- redis 5.0.7 源码阅读——整数集合intset
redis中整数集合intset相关的文件为:intset.h与intset.c intset的所有操作与操作一个排序整形数组 int a[N]类似,只是根据类型做了内存上的优化. 一.数据结构 ty ...
- 多图解释Redis的整数集合intset升级过程
redis源码分析系列文章 [Redis源码系列]在Liunx安装和常见API 为什么要从Redis源码分析 String底层实现——动态字符串SDS 双向链表都不懂,还说懂Redis? 面试官:说说 ...
- 大数据技术之_16_Scala学习_07_数据结构(上)-集合
第十章 数据结构(上)-集合10.1 数据结构特点10.1.1 Scala 集合基本介绍10.1.2 可变集合和不可变集合举例10.2 Scala 不可变集合继承层次一览图10.2.1 图10.2.2 ...
随机推荐
- Ubuntu18.04 显卡驱动安装(解决各种疑难杂症)
步骤 下载驱动 准备工作 进行安装 检查安装 下载驱动 首先我们需要去官网下载显卡驱动 打开浏览器,在百度搜索框中搜索:显卡驱动 下载 在手动搜索驱动程序一栏,根据自己的显卡进行选择 产品系列中,No ...
- Matplotlib直方图绘制技巧
情境引入 我们在做机器学习相关项目时,常常会分析数据集的样本分布,而这就需要用到直方图的绘制. 在Python中可以很容易地调用matplotlib.pyplot的hist函数来绘制直方图.不过,该函 ...
- spring学习五:Spring Bean 定义继承
Bean 定义继承 bean 定义可以包含很多的配置信息,包括构造函数的参数,属性值,容器的具体信息例如初始化方法,静态工厂方法名,等等. 子 bean 的定义继承父定义的配置数据.子定义可以根据需要 ...
- Android 高德地图使用小记
感谢大佬:https://www.cnblogs.com/devilmaycry812839668/p/8727569.html 高德地图 Android编程中 如何设置使 标记 marker 能够被 ...
- Nginx http重定向https
SSL证书申请的腾讯的,配置好证书后,直接监听80端口转发443就ok了 转发语句:rewrite ^/(.*) https://$server_name:443$request_uri? perma ...
- Python—列表元组和字典
Python-列表元组和字典 列表 元组 字典 列表: 列表是Python中的一种数据结构,他可以存储不同类型的数据.尽量存储同一种类型 列表索引是从0开始的,我们可以通过索引来访问列表的值. 列表的 ...
- JS 获取JSON返回的时间值转换为通常格式展示
var date = new Date(parseInt(数据源.slice(6))); //获取到时间 年月日时分秒 var result = date.getFullYear() + '/' ...
- 详解Java12新增语法switch表达式
引言 在学习分支语句的时候,我们都学过 switch 语句,相比于 if-else 语句,他看起来更加整洁,逻辑更加清晰,Java中当然也给我们提了相关的 switch 方法.但是Java的强大之处在 ...
- 垃圾陷阱 && [NOIP2014 提高组] 飞扬的小鸟
#include<bits/stdc++.h> using namespace std; int d,n,dp[1010]; struct node{int t,f,h;} a[1010] ...
- CentOS8上安装MySQL
没有选择Win10上安装MySQL,个人感觉比较傻瓜式.同时相对Win10操作系统,个人更熟悉Unix/Linux操作系统,所以选择在CentOS8上安装MySQL数据库. 还是熟悉的yum安装,前提 ...