复述整数集为什么不能降级

  介绍

本篇内容主要讲解“复述整数集为什么不能降级”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“复述整数集为什么不能降级”吧!

<编辑类="目录">目录 <李>

前言

<李>

基本结构

<李>

何时使用intset

<李>

intset

<李>

添加元素

<李>

类型变动

<李>

升级

<李>

加入65535

<李>

旧数据移位

<李>

降级

<李>

为什么不实现降级


前言

整数集合相信有的同学没有听说过,因为复述对外提供的只有封装的五大对象!而我们本系列主旨是学习复述,内部结构。内部结构是复述,五大结构重要支撑!

前面我们分别从复述,内部结构分析了复述的列表,散列,Zset三种数据结构了。今天我们再来分析组数据结构内部是如何存储的

基本结构

在src/t_set。c中我们发现这样一段代码

redis整数集为什么不能降级

由此我们可知在set中是由两种数据结构构成的: hashtable+intset 。关于redis内部其他的结构我专门在【redis专栏中有介绍】。hashtable不是我们今天的主角,我们今天先分析intset俗称整数集合。

redis整数集为什么不能降级

从上图中我们可以看出,我构造了两个set集合分别为【commonset】、【cs】。两个集合前者存储字符串、后者专门存储数字。

我们在通过object encoding key 来查看下两个集合的底层数据结构,发现一个是hashtable 一个是intset 。这也验证了我们上面对set基本结构的描述。

在redis中对外提供五大类型实际上都是redis的一个抽象对象叫做redisobject。在内部映射了我们redis内部的数据结构

redis整数集为什么不能降级

针对commonset和cs两个集合在内部数据结构大概可以这么理解

redis整数集为什么不能降级

何时使用intset

你可以单纯的认为只要是数字就会使用intset结构来存储,我恐怕要给你当头一棒了。实际上并不是这样

需要同时满足以下两个条件:

redis整数集为什么不能降级

redis整数集为什么不能降级

intset

redis整数集为什么不能降级

图中表示的很清楚了,在intset中的encoding有三种取值分别代表contents保存数据类型。这里有人可能会有疑问了contents的类型不就是int8_t吗?为什么还需要encoding呢?这里通过源码跟踪内部的确跟int8_t没啥关系。而且数据的默认类型就是int16_t 。关于length这里无需太多解释,记住一点表示contents元素的个数并非表示contents数组的长度!

了解intset的同学都知道在encoding三种取值范围中涉及了升级的操作!在讲升级之前我们先来了解下C、C++中int的取值范围是如何定义的

int8_t的取值范围是【-128,127】 。 类似于java中byte占1个字节也就是8位。他的取值范围是

redis整数集为什么不能降级

redis整数集为什么不能降级

添加元素

sadd juejin -123
  sadd  juejin  6
  sadd  juejin  12
  sadd  juejin  56
  sadd  juejin  321 

juejin这个关键内部就是intset。

复述整数集为什么不能降级

上面我们添加了5个元素且这五个元素的长度都在16之内!所以当前的intset的编码=intset_enc_int16. - 123在内容中占前16位。

所以当前五个元素占内容的长度是16 * 5=80;

注意设置在存储int类型数据时,内部是按照从小到大的顺序存储的。

类型变动

复述整数集为什么不能降级

复述整数集为什么不能降级