DBIter的作用
Leveldb数据库的MemTable和sstable文件的存储格式都是InternalKey(userkey, seq, type) => uservalue。
DBIter把同一个userkey在DB中的多条记录合并为一条,综合考虑了userkey的序号、删除标记、和写覆盖等等因素。DBIter只会把userkey最新(seq最大的就是最新的,相同userkey的老记录(seq较小的)不会让上层看到)的一条记录展现给用户,另外如果这条最新的记录是删除类型,则会跳过该记录,否则,遍历时会把已删除的key列举出来。
DBIter的实现原理
class DBIter: public Iterator {
enum Direction {
kForward,
kReverse
};
private:
DBImpl* db_;
const Comparator* const user_comparator_;//比较iter间userkey
Iterator* const iter_;//是一个MergingIterator
SequenceNumber const sequence_;//DBIter只能访问到比sequence_小的kv对
//这就方便了老版本(快照)数据库的遍历
Status status_;
std::string saved_key_; //用于方向遍历 direction_==kReverse时才有效
std::string saved_value_; //用于反向遍历 direction_==kReverse时才有效
Direction direction_;
bool valid_;
Random rnd_;
ssize_t bytes_counter_;
}
iter_是DBImpl::NewInternalIterator创建的结果
std::vector<Iterator*> list;
list.push_back(mem_->NewIterator());//加入memtbale的迭代器
list.push_back(imm_->NewIterator());//加入immemtbale的迭代器
versions_->current()->AddIterators(options, &list);//可以简单理解为加入所以sst文件的迭代器
Iterator* internal_iter =
NewMergingIterator(&internal_comparator_, &list[0], list.size());
iter_是由NewInternalIterator创建的一个MergingIterator,通过MergingIterator可以实现多个有序数据集合的归并操作。其中包含多个child iterator组成的集合。对MergingIterator的遍历会有序的遍历其child iterator中的每个元素。
因为iter_遍历的是数据库的每一条记录。它是以InternalKey(userkey, seq, type)为遍历粒度的,只要InternalKey中任意一个组成元素不同,MergingIterator就认为他们是不同的kv对。
而DBIter是以userkey为遍历粒度的,只要记录的userkey相同,那么DBIter就认为他们是一条记录(不同版本),sqe越大代表该记录越新。每次迭代将跳到下一个不同userkey的记录。