第五章 跳跃表
作者:互联网
跳跃表 在每个节点维持多个指向其他节点的指针,达到快速访问节点的目的。Redis使用跳跃表作为有序集合键的底层实现之一。
5.1 跳跃表的实现
redis.h/zskiplistNode表示跳跃表节点。redis.h/zskiplist保存跳跃表节点的相关信息:节点数量、指向表头表尾节点的指针等。
zskiplist结构:
- header:指向跳跃表的表头节点
- tail:指向跳跃表的表尾节点
- level:记录目前跳跃表内,层数最大的那个节点层数(表头节点的层数不计算在内)
- length:表中节点的数量,不包含表头
zskiplistNode结构:
- level:用L1、L2....表示层。每层带有两个属性:前进指针和跨度。前进指针指向了一个可以访问的节点,跨度记录了当前节点和下一个可访问节点的距离。层数越多,访问其他节点就越快
- backward指针:指向前一个节点,从表尾向表头遍历时使用
- score:记录该节点代表的分值,如图中的1.0,2.0,3.0,所有节点按照分值从小到大排列
- obj:各个节点保存的成员对象,如图中o1,o2,o3
5.1.1 跳跃表节点
type struct zskiplistNode{ //后退指针 struct zskiplistNode *backward; //分值 double score; //成员对象 obj *obj; //层 struct zskiplistLevel{ //前进指针 struct zskiplistNode *forward; //跨度 unsigned int span; } level[]; }zskiplistNode;
1. 层
跳表节点的level数组包含多个元素,每个元素代表一层。层数大小在1~32之间随机生成。
2. 前进指针
通过每层的前进指针(level[i].forward)遍历整个调整的节点,知道遇到NULL。
3. 跨度
层的跨度(level[i].span)记录了该层指向的下一个节点的距离。指向NULL的层的跨度为0。在遍历的过程,记录访问路径上每个层数的跨度,当到达目的节点时,累加得到的跨度就是目的节点在跳跃表中的排位。
4. 后退指针
每个节点只有一个后退节点
5. 分值和成员
节点的分值(score属性)是一个double类型的浮点数,节点按照各自的分值从小到大排列
节点的成员对象(obj属性)是一个指针,它指向一个字符串对象,而字符串对象存放着一个SDS值
节点的分值可以相同,但成员对象必须唯一。当分值相同时,根据保存的字符串对象在字典中的顺序排序。
5.1.2 跳跃表
zskiplist是为了更方便的操作跳跃表,其中包含了可以访问跳表表头和跳表表尾的指针,或是快速获取跳表节点的数量。
标签:分值,表头,第五章,跳跃,跨度,节点,指针 来源: https://www.cnblogs.com/walker993/p/14425990.html