跳表
就是分层级的有序链表
查询数据快,结构简单
跳表所有层级的第一个元素都是header的头元素(空数据)
结尾是实际插入的元素
跳表的第一个实际插入的元素是回退不到header的
代码中
forward的处理是遍历循环处理
backward的处理是一个if判断
是因为forward是层级相关的,所有层级都要处理
而backward只是一个值,backward本身只记录0级的数据
相关文件
相关概念
- strtod
原型double strtod(const char *nptr,char **endptr);
将字符串转化为double
数据结构
1 | /* ZSETs use a specialized version of Skiplists */ |
主要宏
1 |
函数分析
zskiplistNode *zslCreateNode(int level, double score, robj *obj);
功能
创建一个跳表节点
一个节点,一旦创建出来就已经决定了它自身的层级
所以它的数组内存是固定的
不需要在后面扩展层级数据信息
源码
1 | zskiplistNode *zslCreateNode(int level, double score, robj *obj) { |
zskiplist *zslCreate(void);
功能
创建跳表
源码
1 | zskiplist *zslCreate(void) { |
void zslFreeNode(zskiplistNode *node);
功能
释放节点内存
源码
1 | void zslFreeNode(zskiplistNode *node) { |
void zslFree(zskiplist *zsl);
功能
释放跳表内存
源码
1 | void zslFree(zskiplist *zsl) { |
int zslRandomLevel(void);
功能
返回一个随机的跳表层级算法
源码
1 | /* Returns a random level for the new skiplist node we are going to create. |
zskiplistNode *zslInsert(zskiplist *zsl, double score, robj *obj);
功能
跳表插入数据
这里的跳表没有检测重复数据信息
因为redis的跳表是配合dict使用的
判断数据是否重复使用dict来判断
源码
1 | zskiplistNode *zslInsert(zskiplist *zsl, double score, robj *obj) { |
void zslDeleteNode(zskiplist *zsl, zskiplistNode *x, zskiplistNode **update);
功能
删除节点
不是放内存
只是整理跳表的元素结构关系
update为所有相关的需要处理的节点列表
源码
1 | /* Internal function used by zslDelete, zslDeleteByScore and zslDeleteByRank */ |
int zslDelete(zskiplist *zsl, double score, robj *obj);
功能
根据积分和对象删除跳表节点
源码
1 | /* Delete an element with matching score/object from the skiplist. */ |
static int zslValueGteMin(double value, zrangespec *spec);
功能
判断值是否大于(等于)最小范围
源码
1 | static int zslValueGteMin(double value, zrangespec *spec) { |
int zslValueLteMax(double value, zrangespec *spec);
功能
判断值是否小于(等于)最大范围
源码
1 | int zslValueLteMax(double value, zrangespec *spec) { |
int zslIsInRange(zskiplist *zsl, zrangespec *range);
功能
判断跳表是否在给定范围内
源码
1 | /* Returns if there is a part of the zset is in range. */ |
zskiplistNode *zslFirstInRange(zskiplist *zsl, zrangespec *range);
功能
获取到跳表第一个在范围内的元素
源码
1 | /* Find the first node that is contained in the specified range. |
zskiplistNode *zslLastInRange(zskiplist *zsl, zrangespec *range);
功能
获取最后一个在给定范围内的元素
源码
1 | /* Find the last node that is contained in the specified range. |
unsigned long zslDeleteRangeByScore(zskiplist *zsl, zrangespec *range, dict *dict);
功能
根据分数范围删除跳表内的元素
dict是同时删除dict内的记录
源码
1 | /* Delete all the elements with score between min and max from the skiplist. |
unsigned long zslDeleteRangeByLex(zskiplist *zsl, zlexrangespec *range, dict *dict);
功能
根据范围对象删除跳表元素
dict是同时删除dict内的记录
源码
1 | unsigned long zslDeleteRangeByLex(zskiplist *zsl, zlexrangespec *range, dict *dict) { |
unsigned long zslDeleteRangeByRank(zskiplist *zsl, unsigned int start, unsigned int end, dict *dict);
功能
根据rank的起始和结束位置删除跳表数据
dict是同时删除dict内的记录
源码
1 | /* Delete all the elements with rank between start and end from the skiplist. |
unsigned long zslGetRank(zskiplist *zsl, double score, robj *o);
功能
根据积分和对象查找在跳表中的rank信息
不存在则返回0
源码
1 | /* Find the rank for an element by both score and key. |
zskiplistNode* zslGetElementByRank(zskiplist *zsl, unsigned long rank);
功能
根据rank信息查找对应的跳表元素
源码
1 | /* Finds an element by its rank. The rank argument needs to be 1-based. */ |