Level DB --- filter_block
filter_block里面包含FilterBlockBuilder和FilterBlockReader,他们是Level DB中读、写Filter(Level DB --- BloomFilterPolicy-CSDN博客)重要的类,相当于是FIlter的一个Wrapper,将Filter有组织地写(序列化)和读(反序列化)。
FilterBlockBuilder
AddKey
当需要计算filter的时候,不会上来就调用FIlter(Level DB --- BloomFilterPolicy-CSDN博客),而是首先进行预存,如图1所示,其中keys_是FilterBlockBuilder中的数据成员,它是一个string,用来缓存新加入的key value,start_也是FilterBlockBuilder中的数据成员,它是一个vector,用来记录新加入key在keys_中的index。
图1. add key
StartBlock
随着key的不断加入,会存在一个阈值,达到这个阈值,就将keys_中的这些记录计算一波filter。计算的阈值源码计算如下:
void FilterBlockBuilder::StartBlock(uint64_t block_offset) {
uint64_t filter_index = (block_offset / kFilterBase);
assert(filter_index >= filter_offsets_.size());
//可以理解每kFilterBase个key存储到一个单元里面
while (filter_index > filter_offsets_.size()) {
GenerateFilter();
}
}
GenerateFilter
当keys_里面存储的数量达到kFIlterBasey以上或是finish的时候,会触发一次hash array的计算和hash array的记录。如图2所示,hash array 是Filter(Level DB --- BloomFilterPolicy-CSDN博客)计算的。filter_offset_记录每次hash array的offset,result_是一个string,每次计算好的hash array会附加在result中。
图2. add hash array record
Finish
当完成了整体的key的filter的计算,会进行序列化,序列化的格式如图3所示。这里面第3项记录的是hash arrays数据在result_中的offset。
图3. 序列化 result_
这里有一行代码,这里面阴性将static const size_t kFilterBaseLg = 11,转化为一个char。
result_.push_back(kFilterBaseLg); // Save encoding parameter in result
FilterBlockReader
FilterBlockReader的构造函数主要是从contents中解析出来FilterBlockBuilder中序列化的数据,而KeyMayMatch计算offset所在的hash array其实就是上述介绍序列化的逆过程。