inset是Redis中set类型的一种底层存储结构(编码),它是基于整数数组来实现的,用于存储数值类型set集合数据,并具备长度可变、有序等特征。
有序性
为了方便查找,Redis会将intset中整数数据按照从小到大的顺序排序,存放在content中,如下图:
为什么需要统一编码?
content中的每个元素分配的长度都是相同的比如2字节、4字节、8字节,比如有些元素可以使用1字节存储,有些需要4字节存储,那么为什么要统一使用编码长度呢?
-- 是为了方便指针查找,C语言中都是通过指针的偏移来定位元素的,知道元素的长度,可以更方便偏移指针。
比如找到下标2的元素,则将指针向右偏移 : 0+2*2字节即可。
intSet动态升级
上面了解content中元素是统一编码长度的,如果新加入更大编码长度元素时,intset需要保持统一编码长度,升级当前编码类型为适合的编码类型,然后进行内存的重新分配调整过程。
此时加入元素50000,需要使用4字节存储,则循需要升级为INTSET_ENC_INT32:
注意:因为要保持编码长度统一,所以5,10,20都需要升级为32位4字节存储
升级流程 :
- 判断新数据50000大小,选择合适的编码类型INTSET_ENC_INT32,并按照新的编码类型计算(每个元素占4字节),并申请总空间。
- 倒叙一次将数组中的元素拷贝到扩容后的空间中。(如果正序,5元素拷贝后会覆盖10元素原来空间内容,造成元素覆盖)
- 完成原数据升级后,将新数据50000加入到数组尾部
- 修改header中encoding和len信息。