Redis 跳表 zskiplist
1. 用途
- 用于实现Redis中的有序集合
- 用于在一个集群节点中用于内部数据结构
2. 数据定义
2.1 zskiplist (redis.h/zskiplist)
typedef struct zskiplist{
struct skiplistNode*header,tail;
unsigned long length;
int level;
}zskiplist;
- head,tail skiplistNode 指针用于指向调表中的头节点和尾节点
- length 当前跳跃表的长度 也就是包含的节点数量 头节点不包含在内
- level 当前所有节点中的最高层级 头节点不包含在内
2.2 zskiplistNode (redis.h/zskiplistNode)
typedef struct zskiplistNode
{
struct zskiplistNode*backward;
double score'
robj*obj;
struct zskipLevel{
struct zskiplistNode*forward;
unsigned int span;
}level[];
}zskiplistNode;
- backward 后退指针 用于从尾部节点向头节点遍历 并且只能一个个的节点进行遍历 遇到NULL就结束
- score double类型用于保存分数
- obj 指针指向一个SDS(简单动态数组) 保存节点的键
- level[n].forward 某个层级的前进指针
- level[n].span 某个层级的跨度 用于记录当前节点与下一个节点之间的距离,跨度与遍历的操作无关对于遍历只能一个个节点的往后进行,跨度是用来计算排位的,在访问某个节点的过程中 将沿途访问过的所有层的跨度加起来就会得到排位
2.4 具体说明
- level = 5 是计算的所有节点的最高层级数 也就是节点三的层级数 表头节点不包括在内
- span 表示当前节点与下一个同层级节点的距离
- 对于跳表来说访问头尾节点的时间复制度是O(1)
- 对于获取调表的长度来说时间复杂度也是O(1)
- 对于节点的查找 插入和删除等操作的时间复杂度 平均是O(lgn) 最坏是O(n)
3. API
函数 | 作用 |
---|
zslCreate | 创建一个新的跳跃表 |
zslFree | 释放一个跳表以及当中的所有节点 |
zslInsert | 添加新的节点到跳表 |
zslDelete | 删除指定的跳表节点 |
zslGetRank | 返回包含指定节点在表中的排位 |
zslGetElementByRank | 返回指定排位的所指向的节点 |
zslIsInRange | 给定一个分值范围 ,如果给定的范围在跳表的分值范围内返回1 否则返回0 |
zslFirstInRange | 给定一个分值范围 给出第一个符合这个范围的节点 |
zslLastInRange | 给定一个分值范围 返回最后一个符合这个范围的节点 |
zslDeleteRangeByScore | 给定一个分值范围 删除表中所有符合这个范围内的节点 |
zslDeleteRangeByRank | 给定一个排位的范围 删除表中在这个范围内的节点 |