以下介绍都来自rocksdb 6.15.5版本。
get流程
我们知道Rocksdb的get流程是先从mem,再到immem。之后就是各个sst里面搜索。
具体的逻辑在BlockBasedTable::Get里面。
在这里面就是先读到indexblock,再通过NewDataBlockIterator方法使用indexblock构造出datablcok
Iterator流程
当用户做如下调用
ReadOptions readOptions;rocksdb::Iterator* it = db->NewIterator(readOptions);
最终调用的是DBImpl::NewInternalIterator,返回了一个InternalIterator指针。里面包含了Mem,Imem,L0等等各层的迭代器。
对于具体的某个sst来说,先创建IndexReader,在创建IndexReader的时候,是根据index_type来确定的,其结构如下:
enum IndexType : char {kBinarySearch = 0x00,kHashSearch = 0x01,kTwoLevelIndexSearch = 0x02,kBinarySearchWithFirstKey = 0x03,
};
系统默认使用的是kBinarySearch。因此默认情况下IndexReader指的是BinarySearchIndexReader。
再通过IndexReader产生IndexBlockIter。
最后在BlockBasedTable::NewIterator里面,把IndexBlockIter给了BlockBasedTableIterator,用户真正持有的也是BlockBasedTableIterator。
在对单个sst进行迭代的时候,我们会发现BlockBasedTableIterator里面有两个变量:
// 进行sst的迭代器操作的时候 index_iter_ 和 block_iter_是一组std::unique_ptr<InternalIteratorBase<IndexValue>> index_iter_;DataBlockIter block_iter_;
单个sst的迭代器如上,如果碰到对L1,L2这种一层进行迭代,那是用的就是LevelIterator。
LevelIterator里面有个file_iter_,就是这一层里面的某个具体sst的迭代器,它的确定是在version_set.cc ::NewFileIterator里面完成的。
以上逻辑和TwoLevelIterator没有关系。
参考资料
https://blog.csdn.net/dlf123321/article/details/140840457
https://blog.csdn.net/Z_Stand/article/details/111712716