redis学习笔记(5)---整数集合intset

intset

  当一个集合中只包含整数,且这个集合中的元素数量不多时,redis就会使用整数集合intset作为集合的底层实现。

整数集合的实现

typedef struct intset {
    uint32_t encoding;
    uint32_t length;
    int8_t contents[];
} intset;
  • encoding:当前整数集合的编码方式
  • length:集合中的元素个数
  • contents:集合中元素的具体存储位置

  redis整数集合有三种编码方式:
  1)INTSET_ENC_INT16,那么contents数组就是一个int16_t类型的数组,数组中的每一项都是一个int16_t类型的整数,范围为-32768~32767
  2)INTSET_ENC_INT32,那么contents是一个int32_t类型的数组
  3)INTSET_ENC_INT64,那么contents是一个int64_t类型的数组

示意图

  一个简单的示意图如下:
  redis学习笔记(5)---整数集合intset_第1张图片
  数组中的每个元素都是int16_t类型的,2个字节,一个有5个元素,因此contents数组占用的空间为 16*5/8=10字节

升级

  假设原有整数集合为:
  redis学习笔记(5)---整数集合intset_第2张图片
  此时contents数组占用的空间为16*3=48位
  对于int16_t类型的元素,其范围为-32768~32767,当新加入一个值为65535的元素时,int16_t类型就不足以存放该元素,因此此时就要对整数集合进行升级。
  该元素用int32_t足够存储,因此要将整数集合的编码方式升级为INTSET_ENC_INT32。
  这样就需要 32*4=128位的空间,每个元素占4个字节。
  因此升级的步骤为:
  1)根据新元素的类型,扩展底层数组的空间大小,并分配空间
  2)将底层所有元素都转换成新元素相同的类型,并将转换后的元素放到新分配的空间中。在放置元素的过程中,需要维持底层数组的有序性质不变
  3)将新元素加入到底层数组中
  由于新加入的元素导致升级,因此新元素的大小一定比之前所有的元素都大,因此将新元素存放在contents数组的最后一项即可
  升级后的整数集合为:
  redis学习笔记(5)---整数集合intset_第3张图片
  contents数组中的元素存放顺序为:
  redis学习笔记(5)---整数集合intset_第4张图片
  
  整数集合不支持降级操作



本文所引用的源码全部来自Redis3.0.7版本

redis学习参考资料:
https://github.com/huangz1990/redis-3.0-annotated
Redis 设计与实现(第二版)

你可能感兴趣的:(redis学习笔记(5)---整数集合intset)