概述

Rocksdb提供了几种基本的操作接口,其中Get()就是用来查找key-value pair,原理也非常简单,就是顺着Memtable,Immutable memtable, 然后SST文件查找。因为Rocksdb支持column family,所以调用时有个可选参数ColumnFamilyHandle*,如果没有指定即调用默认的column family。

实现

Rocksdb的接口操作实现与Leveldb类似,定义一个抽象基类Rocksdb::DB,其中定义一些纯虚函数,包括Get,Put操作等,定义一个子类rocksdb::DBImpl实现这些接口。

来看一下rocksdb::DBImple定义的Get接口实现,原理比较简单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Status DBImpl::GetImpl(const ReadOptions& read_options,
ColumnFamilyHandle* column_family, const Slice& key,
PinnableSlice* pinnable_val, bool* value_found,
ReadCallback* callback, bool* is_blob_index) {
// 获取column family里面的数据,包括memtable和immutable
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
auto cfd = cfh->cfd();
// ...
if (!skip_memtable) {
// 进入memtable中查找key
if (sv->mem->Get(lkey, pinnable_val->GetSelf(), &s, &merge_context,
&range_del_agg, read_options, callback, is_blob_index)) {
// ...
} else if ((s.ok() || s.IsMergeInProgress()) &&
// 进入immutable中查找key
sv->imm->Get(lkey, pinnable_val->GetSelf(), &s, &merge_context,
&range_del_agg, read_options, callback,
is_blob_index)) {
// ...
}
// ...
}
if (!done) {
// 迭代SST文件查找
sv->current->Get(read_options, lkey, pinnable_val, &s, &merge_context,
&range_del_agg, value_found, nullptr, nullptr, callback,
is_blob_index);
RecordTick(stats_, MEMTABLE_MISS);
}
// ...
}

Memtable和Immutable的查找就是通过MemTableRep::Get()对上篇所讲的SkipList数据结构调用FindGreaterOrEqual()查找,SST文件查找将会在之后的SST分析里介绍。