redis源码阅读笔记(4)——skiplist
0.跳表基础知识跳表(skiplist)是一种有序数据结构, 它通过在每个节点中维持多个指向其他节点的指针, 从而达到快速访问节点的目的。
跳跃表支持平均 O(log N) 最坏 O(N) 复杂度的节点查找, 还可以通过顺序性操作来批量处理节点。
在大部分情况下,跳跃表的效率可以和平衡树相媲美,并且因为跳跃表的实现比平衡树要来得更为简单,所以有不少程序都使用跳跃表来代替平衡树。
一个跳表的图示如下
可以看到如果要查找117这个元素,可以沿着红线的方向,“跳”着找,最终找到117,所以效率很高。
参考资料
SkipList 跳表
在JDK6中也加入了跳表的实现ConcurrentSkipListMap和ConcurrentSkipListSet,
他们的功能相当于JDK6以前的TreeMap和TreeSet(两者都采用红黑树来实现),只不过新的跳表更高级了,支持高并发。
1.高层视角解读
请先看这篇文章
跳跃表的实现
redis中的skiplist的数据结构如图所示
2.底层代码
API定义请看redis.h/zskiplistNode 和 redis.h/zskiplist
API实现请看t_zset.c,将近4000行代码。
span的作用?
跨度实际上是用来计算排位(rank)的: 在查找某个节点的过程中, 将沿途访问过的所有层的跨度累计起来, 得到的结果就是目标节点在跳跃表中的排位。
可以看zslGetRank函数的代码,正是有了这个span,使得计算一个元素的rank可以非常的高效!
页:
[1]