SStable的写入 - KV存储-LevelDB/RocksDB源码剖析和中文注释

请教:简书如何写代码块?

Overview

Index Block and Data Block

2.Index Block是怎么存储各个Data Block的索引信息的。The two lines below are key codes:

r->pending_handle.EncodeTo(&handle_encoding);

r->index_block.Add(r->last_key, Slice(handle_encoding));

可以看出,Index Block的key是last_key,它的含义就是大于当前Data Block中的所有key,并且小于下一个Data Block中的所有key。

比如上一个data block最后一个k/v的key是"the quick brown fox",其后继data block的第一个key是"the who",我们就可以用一个较短的字符串"the r"作为上一个data block的index block entry的key。

value是BlockHandle,它由uint64_t offset 和uint64_t size_组成,其含义就是小于last_key的kv对所在的Data Block所在的文件偏移以及长度。

3.**table_builder的Add"间接"借助了block_builder的Add,但是并非显示的直接调用block_builder的Add。

4.在写sstable文件时,往文件中写一个Data Block后便向内存中的index_block插入一条记录,当所有Data Block全部写入文件后,才将内存中的index_block写入sstable文件中。Where is the corresponding codes?

TableBuilder类

构建sstable文件的类是TableBuilder,该类提供了几个有限的方法可以用来添加k/v对,Flush到文件中等等,它依赖于BlockBuilder来构建Block。

TableBuilder的几个接口说明下:

> void Add(const Slice& key, const Slice& value),向当前正在构建的表添加新的{key, value}对,要求根据Option指定的Comparator,key必须位于所有前面添加的key之后;

> void Flush(),将当前缓存的k/v全部flush到文件中,一个高级方法,大部分的client不需要直接调用该方法;

> void Finish(),结束表的构建,该方法被调用后,将不再会使用传入的WritableFile;

> void Abandon(),结束表的构建,并丢弃当前缓存的内容,该方法被调用后,将不再会使用传入的WritableFile;【只是设置closed为true,无其他操作】

一旦Finish()/Abandon()方法被调用,将不能再次执行Flush或者Add操作。

下面来看看涉及到的类,如图6.3-1所示。


其中WritableFile和op log一样,使用的都是内存映射文件**。

TableBuilder只有一个成员变量Rep* rep_,实际上Rep结构体的成员就是TableBuilder所有的成员变量;这样做的目的,可能是为了隐藏其内部细节。Rep的定义也是在.cc文件中,对外是透明的。

Related Source Code  Chinese Comments