跳跃表(skiplist)
跳跃表的实现
typedef struct zskiplist{
//表头表尾节点
struct skiplistNode *header,*tail;
//表中节点数量
unsigned long length;
//表中最大的节点层数
int level;
} zskiplist;
typedef struct zskiplistNode{
struct zskiplistLevel{
//前进指针
struct zskiplistNode *forward;
//跨度
unsigned int span;
} level[];
//后退指针
struct zskiplistNode *backward;
//分值
double score;
//成员对象
obj *obj;
} zskiplistNode;
展示图:
总结
1.跳跃表是有序集合的底层实现之一。
2.Rcdis的 跳 跃 表 实 现 由zskiplist和zskiplistNode两 个 结 构 组 成 , 其 中zskiplist用P保 存 跳 跃 表 信 息 ( 比 如 表 头 节 点 、 表 尾 节 点 、 长 度 而zskiplistNode则 用P表 示跳跃表节点。
3.每个跳跃表节点的层卨都是1至32之间的随机数。
4.在同一个跳跃表中,多个节点可以包含相同的分值,但每个节点的成员对象必须是 唯一的。
5.跳跃表中的节点按照分值大小进行排序,当分值相同时,节点按照成员对象的大小进行排序。
整数集合
集合键的底层实现之一,当一个集合只包含整数值元素时,并且整个集合的元素数量不多时,就会使用该数据结构作为集合键的底层实现。
整数集合的实现
typedef struct intset{
//编码方式
uint32_t encoding;
//集合包含的元素数量
uint32_t length;
//保存元素的数组
int8_t contents[];
} intset;
contents数组是整数集合的底层实现:整数集合的每个元素都是contents数组的-一个数组项( item),各个项在数组中按值的大小从小到大有序地排列,并且数组中不包含任何重复项。
encoding
encoding | 最小值,最大值 |
---|---|
INTSET_ ENC_ INT16 | -32768,32767 (-215~215-1) |
INTSET_ ENC_ INT32 | -2147483648,2147483647 (-231~231-1) |
INTSET_ ENC_ INT64 | (-263~263-1) |
升级(upgrade) (不支持降级)
每当我们要将一个新元素添加到整数集合里面,并且新元素的类型比整数集合现有所有元素的类型都要长时,整数集合需要先进行升级( upgrade),然后才能将新元素添加到整数集合里面。
三个步骤:
- 根据新元素的类型,扩展整数集合底层数组的空间大小,并为新元素分配空间。
- 将底层数组现有的所有元素都转换成与新元素相同的类型,并将类型转换后的元素放置到正确的位上,而且在放置元素的过程中,需要继续维持底层数组的有序性质不变。
- 将新元素添加到底层数组里面
引发升级的新元素摆放位置:当大于所有元素,放在最末尾(length-1); 小于所有元素,则放在最开头(0)
好处:
- 提升灵活性:因为整数集合可以通过自动升级底层数组来适应新元素,所以我们可以随意地将int16_ t、int32 _ t或者int64_ t 类型的整数添加到集合中,而不必担心出现类型错误,这种做法非常灵活。
- 节约内存
总结
-
整数集合是集合键的底层实现之一。
-
整数集合的底层实现为数组,这个数组以有序、无重复的方式保存集合元素,在有
需要时,程序会根据新添加元素的类型,改变这个数组的类型。 -
升级操作为整数集合带来了操作上的灵活性,并且尽可能地节约了内存。
-
整数集合只支持升级操作,不支持降级操作。
压缩列表
压缩列表(ziplist)是列表键和哈希键的底层实现之一。当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做列表键的底层实现。
展示图:
属性 | 类型 | 长度 | 用途 |
---|---|---|---|
zlbytes | uint32_ t | 4字节 | 记录整个压缩列表占用的内存字节数:在对压缩列表进行内存重分配,或者计算zlend的位置时使用 |
zltail | uint32_ t | 4字节 | 记录压缩列表表尾节点距离压缩列表的起始地址有多少字节:通过这个偏移量,程序无须遍历整个压缩列表就可以确定表尾节点的地址 |
zllen | uint16_ t | 2字节 | 记录了压缩列表包含的节点数量:当这个属性的值小于( 65535)时,这个属性的值就是压缩列表包含节点的数量;当这个值等于UINT16_ MAX时,节点的真实数量需要遍历整个压缩列表才能计算得出 |
entryX | 列表节点 | 不定 | 压缩列表包含的各个节点,节点的长度由节点保存的内容决定 |
zlend | uint8_ t | 1字节 | 特殊值0xFF (十进制255),用于标记压缩列表的末端 |
总结
- 压缩列表是一种为节约内存而开发的顺序型数据结构。
- 压缩列表被用作列表键和哈希键的底层实现之一。
- 压缩列表可以包含多个节点,每个节点可以保存一一个字节数组或者整数值。
- 添加新节点到压缩列表,或者从压缩列表中删除节点,可能会引发连锁更新操作,但这种操作出现的几率并不高。