整数(intset)
整数汇合是汇合键的底层实现之一,当一个汇合只蕴含整数元素,并且元素数量不多时,就会用它
整数汇合时Redis用于保留数值的,它能够保留int16_t、int32_t、nt64_t
别离对应short int long
insert.h
typedef struct intset { // 编码方式 uint32_t encoding; // 汇合蕴含的元素数量 uint32_t length; // 保留元素的数组 int8_t contents[];} intset;/* * intset 的编码方式 */#define INTSET_ENC_INT16 (sizeof(int16_t))#define INTSET_ENC_INT32 (sizeof(int32_t))#define INTSET_ENC_INT64 (sizeof(int64_t)
整数汇合的每个元素都是contents数组的一个数组项,它是从小到大排列的,并且不蕴含反复。
你会发现这里的contents是int8_t也就是char、然而实际上contents不保留任何的char、contents数组真正类型却决与encoding属性的值。
- 如果encoding 为INTSET_ENC_INT16、那么contents就是一个int16_t类型的数组,short(最小值-32768、最大值32767)
- 如果encoding 为INTSET_ENC_INT32、那么contents就是一个int32_t类型的数组,int(最小值-2147483648、最大值2147483647)
- 如果encoding 为INTSET_ENC_INT64、那么contents就是一个int64_t类型的数组,long(太多了)
降级
如果你向一个int类型的数组中,插入了一个long怎么解决? 降级!!!
1、更具新类型的元素,扩大底层数组空间
2、将底层数组现有所有元素都转换为与新元素雷同的类型,而后进行一个排序,因为contents是有序不反复的
3、最初才是将新元素增加进去
原数组 【1】,【2】,【3】 int16_t 16*3=48插入 65535 int32_t1、重新分配空间大小 32*4=128 但此时之前的数据地位不变,而是在前面增加空间
2、上面就是将转换后元素放到正确的地位,并且要放弃有序性不变先挪动3到 32*2 ~~~ 32*3-1 64 ~~ 95
因为3的地位换了,所有会有肯定的空间空进去 48-63之后同样的情理挪动1和2最初剩下的地位就是留给新元素的将encoding从int16_t变为int32_t
每次向整数汇合增加元素都可能引起降级,所有增加时O(N)
元素如果很小比方-12145641会呈现在头部,元素很大1231564会呈现在尾部。
这样的作法就时节约内存,有须要才会降级
整数的汇合是不反对降级操作的,一旦降级,encoding就不可能变小了
所有这里就呈现一个问题,如果一个数组100个元素,有99个int16,一个int32,那么数组类型就会降级为int32这也时一种节约,这能不能想方法解决呢?