leveldb源码剖析2.2–核心设计之mem缓存

引言

无论是MemTable、还是immutable MemTable,在leveldb源码实现中都是MemTable类型。其核心数据结构是跳表。

1 跳表原理

1.1 数据结构

跳表主要是优化传统有序链表的操作时间复杂度,类似二分查找算法思想。其结构如下图:
在这里插入图片描述
图中是一个最大高度为3的跳表。表头有3个指针域,数据节点为1到3个指针域。所有的指针域指向后续节点的基地址,例如数据域1的level ptr0和头节点的level ptr1都指向数据域2对应节点的基地址。

1.2 数据查询

数据查询核心思想就是查询大于或等于查找数据的节点。以查询数据域4为例,其步骤如下:

  • 首先,在level 2级,从表头开始遍历查询大于或等于数据域4的节点,得到数据域5所在节点。同时,记录level 2与数据域3所在节点的索引关系;
  • 然后,在level 1级,从数据域3所在节点开始遍历查询大于或等于数据域4的节点,得到数据域5所在节点。同时,记录level 1与数据域3所在节点的索引关系;
  • 继续,在level 0级,从数据域3所在节点开始遍历查询大于或等于数据域4的节点,得到数据域4所在节点。同时,记录level 0与数据域3所在节点的索引关系;
  • 最后比较数据域4所在节点是否与数据域4相等,因为相等所以查询成功。

1.3 插入节点

插入节点按照如下的顺序:

  • 首先,根据算法生成一个节点并填充数据域。例如在leveldb中,是通过随机生成高度为1到12不等的节点
  • 然后,查询大于或等于插入数据的节点,得到一个level 0到2的前继节点索引。leveldb中用数组代替索引,即用下标表示level
  • 遍历插入节点的每个level,将插入节点追加到前继节点索引中对应level ptr的后面。

1.4 删除节点

注:删除节点与插入类似,也是借助查询来剔除节点、重建链表指向关系。

2 源码解读

整个MemTable类由两部分组成,即Area类和SkipList模板类。前者是内存池的实现,后者是跳表的模板实现。
在这里插入图片描述
注:Area的实现原理参考上节。
在SkipList只提供了插入、查询、迭代功能,未提供delete操作。之所以没有提供delete操作,是因为MemTable只提供追加数据操作,当我们delete key只是将操作类型追加到数据库中。

猜你喜欢

转载自blog.csdn.net/fs3296/article/details/108115956