Leveldb源码分析--21

本文分析了Leveldb中的DB查询与遍历,包括Get()、NewIterator()方法,以及MergingIterator的Get系和Seek系接口。在MergingIterator部分,详细探讨了接口的功能实现,如通过current_指针获取key和value,以及不同Seek函数的内部调用逻辑。
摘要由CSDN通过智能技术生成

最近工作上事情太多,更新的也比较慢了。

14 DB的查询与遍历之1

分析完如何打开和关闭db,本章就继续分析如何从db中根据key查询value,以及遍历整个db。

14.1 Get()

函数声明:StatusGet(const ReadOptions& options, const Slice& key, std::string* value)
从DB中查询key 对应的value,参数@options指定读取操作的选项,典型的如snapshot号,从指定的快照中读取。快照本质上就是一个sequence号,后面将单独在快照一章中分析。
下面就来分析下函数逻辑:
// S1 锁mutex,防止并发,如果指定option则尝试获取snapshot;然后增加MemTable的引用值。
  MutexLock l(&mutex_);
  SequenceNumber snapshot;
  if (options.snapshot != NULL)
    snapshot =reinterpret_cast<const SnapshotImpl*>(options.snapshot)->number_;
  else snapshot =versions_->LastSequence(); // 取当前版本的最后Sequence
  MemTable *mem = mem_, *imm =imm_;
  Version* current =versions_->current();
  mem->Ref();
  if (imm != NULL) imm->Ref();
  current->Ref();
// S2 从sstable文件和MemTable中读取时,释放锁mutex;之后再次锁mutex。
  bool have_stat_update = false;
  Version::GetStats stats;
  {
    mutex_.Unlock();
    // 先从memtable中查询,再从immutable memtable中查询
    LookupKey lkey(key, snapshot);
    if (mem->Get(lkey, value,&s)) {
    } else if (imm != NULL&& imm->Get(lkey, value, &s)) {
    } else { // 需要从sstable文件中查询
      s = current->Get(options,lkey, value, &stats);
      have_stat_update = true; // 记录之,用于compaction
    }
    mutex_.Lock();
  }
// S3 如果是从sstable文件查询出来的,检查是否需要做compaction。最后把MemTable的引用计数减1。
  if (have_stat_update &¤t->UpdateStats(stats)) {
    MaybeScheduleCompaction();
  }
  mem->Unref();
  if (imm != NULL)imm->Unref();
  current->Unref();
查询是比较简单的操作,UpdateStats在前面Version一节已经分析过。

14.2 NewIterator()

函数声明:Iterator*NewIterator(const ReadOptions& options)
通过该函数生产了一个Iterator*对象,调用这就可以基于该对象遍历db内容了。
函数很简单,调
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值