跳跃表
跳跃表是一种数据结构,Redis的有序集合键的一种实现方式就是跳跃表(当一个有序集合键包含比较多的元素或者它是一个较长的字符串时,Redis会使用跳跃表来实现),跳跃表的优势是实现了最好O(logN),最坏O(N)的查找时间复杂度,且它实现起来较为简单。
跳跃表的结构主要分为跳跃表和跳跃表节点结构:
1.跳跃表结构
跳跃表结构主要包含了跳跃表的信息,比如跳跃表里节点的个数,指向表头和表尾的指针等,它的主要结构如下:
- header: 指向跳跃表的表头节点
- tail:指向跳跃表的表尾节点
- level:记录当前跳跃表除了表头节点外其余节点层数最高节点的层数
- length:记录跳跃表目前包含节点的数量
2.跳跃表节点结构
- 后退指针:跳跃表节点指针,指向当前节点的前一个节点
- 分值:double类型,多个对象的分值可以相同
- 成员对象 :保存一个SDS字符串类型
- 层:结构体,含有前进指针(指向本层的下一个对象)和跨度(前进指针所指向节点距离当前节点的距离)
整数集合
应用整数集合的场景:当一个集合只包含整数值元素,并且这个集合的元素数量不多时,Redis就会使用整数集合作为集合键的底层实现
1.整数集合的结构:
- uint32_t encoding;编码方式
- uint32_t length:集合包含的元素数量(contents数组长度)
- int8_t contents[]:元素数组(由小到大排列且无重复),这里的int8_t并不是说整数集合只能保存8位int类型值,他的元素类型仅由encoding编码方式决定
一般来说,encoding由三种取值方式,分别为INTSET_ENC_INT16(-32768-32767), INTSET_ENC_INT32(-2147483648-2147483647), INTSET_ENC_INT64(-372036854775808-372036854775808)
2.整数集合的升级:
这里的升级主要值一个比当前整数集合编码大的元素插入当前整数集合时整数集合的升级操作(例如一个int_16t的整数集合插入一个int_64t类型的整数),升级的步骤如下:
- 扩展当前数组,增加数组内存大小,并为新元素分配内存
- 将当前数组的每个元素转换类型,将转换后的元素放到新数组里,且保证这些元素有序性不变
- 为这个数组加上新的元素
整数集合支持升级的好处一方面是避免了所有整数均采用int_64t的数组存放,节省内存,另一方面让使用者不用担心类型转换的问题,增加了灵活性
整数集合不支持降级,一旦数组升级后,编码就会一直保持这样的状态