Bootstrap

跳表(Skiplist)

学习levelDB时,其Memtable使用到了Skiplist数据结构,在mongodb的存储引擎WiredTiger中的内存存储结构中也有使用。

基本原理:

跳表(skip List)是一种随机化的数据结构,基于并联的链表,基本思想参考:点击打开链接 。可以用来代替平衡树,以“空间换取时间”,从而提高效率。

跳表具有如下性质:

(1) 由很多层结构组成

(2) 每一层都是一个有序的链表

(3) 最底层(Level 1)的链表包含所有元素

(4) 如果一个元素出现在 Level i 的链表中,则它在 Level i 之下的链表也都会出现。

(5) 每个节点包含两个指针,一个指向同一链表中的下一个元素,一个指向下面一层的元素。


跳表实现简单,插入、删除、查找的复杂度均为O(logn),高度为O(logn)的概率较高,所需存储空间为O(n)。复杂度分析如下:


优缺点:


与skiplsit类似,红黑树的插入、删除、查找操作也都是O(logn)的时间复杂度,但是skiplist具有以下优点:

1.比红黑树实现更加简单;

2.同样支持范围查找;

3.增删改查操作的范围更小一些,锁的代价也就更小,并发度更高(使用CAS操作并发节点)。而红黑树的插入删除元素涉及到树是否平衡,需要进行旋转,甚至可能影响到整棵树;

4.对于skiplist层次的建立,引入了新条件--“概率”。传统的平衡树、红黑树等插入新的元素是否上推依赖于与临近节点,而skiplist则使用随机数,为0则不上推,为1则上推,完全不依赖集合内其他元素。这使得每一次插入都更加“独立”,冲突只发生在真正写入的那一步操作上。对于链表来说,数据的写入是能够做到无锁的写入新数据的,于是,利用skiplist,就能成功的做到无锁的有序平衡“树”(多层级)结构。

5.比起普通链表,解决的不易取到中值的缺点。

缺点:

1.面向磁盘效率低。

磁盘要求顺序写,顺序读,一次读写必须是一整块的数据。而对于skiplist来说,查询中每一次从高层跳跃到底层的操作,都会对应一次磁盘随机读,而skiplist的层数从宏观上来看一定是O(logn)层。因此也就对应了O(logn)次磁盘随机读。因此这个数据结构不适合于磁盘结构。

2.耗内存

由于需要重复分层存储节点,所以相比于其他分层的树结构来说比较耗内存。但是可以调参数降低内存消耗,达到与其他平衡树差不多的性能


参考文章:点击打开链接


;