概述

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接口实现,原理比较简单:

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分析里介绍。