学习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.耗内存由于需要重复分层存储节点,所以相比于其他分层的树结构来说比较耗内存。但是可以调参数降低内存消耗,达到与其他平衡树差不多的性能
参考文章:点击打开链接