最近工作上事情太多,更新的也比较慢了。
14 DB的查询与遍历之1
分析完如何打开和关闭db,本章就继续分析如何从db中根据key查询value,以及遍历整个db。
14.1 Get()
从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*对象,调用这就可以基于该对象遍历db内容了。
函数很简单,调