Leveldb源码分析--22

本文详细分析了Leveldb中DBIter的实现,包括Get系接口、辅助函数、Seek系函数的使用,以及Prev()和Next()的实现细节,揭示了如何在遍历过程中处理被删除的记录。
摘要由CSDN通过智能技术生成

14 DB的查询与遍历之2

14.4 DBIter

Leveldb数据库的MemTable和sstable文件的存储格式都是(user key, seq, type) => uservalue。DBIter把同一个userkey在DB中的多条记录合并为一条,综合考虑了userkey的序号、删除标记、和写覆盖等等因素。
从前面函数NewIterator的代码还能看到,DBIter内部使用了MergingIterator,在调用MergingItertor的系列seek函数后,DBIter还要处理key的删除标记。否则,遍历时会把已删除的key列举出来。
DBIter还定义了两个移动方向,默认是kForward:
1) kForward,向前移动,代码保证此时DBIter的内部迭代器刚好定位在this->key(),this->value()这条记录上;
2) kReverse,向后移动,代码保证此时DBIter的内部迭代器刚好定位在所有key=this->key()的entry之前。
其成员变量savedkey和saved value保存的是KReverse方向移动时的k/v对,每次seek系调用之后,其值都会跟随iter_而改变。
DBIter的代码开始读来感觉有些绕,主要就是它要处理删除标记,而且其底层的MergingIterator,对于同一个key会有多个不同sequence的entry。导致其Next/Prev操作比较复杂,要考虑到上一次移动的影响,跳过删除标记和重复的key。
DBIter必须导出Iterator定义的几个接口,下面就拖出来挨个分析。
14.4.1 Get系接口

首先是几个简单接口,获取key、value和status的:

  virtual Slice key() const { //kForward直接取iter_->key(),否则取saved key
    assert(valid_);
    return (direction_ ==kForward) ? ExtractUserKey(iter_->key()) : saved_key_;
  }

  virtual Slice value() const { //kForward直接取iter_->value(),否则取saved value
    assert(valid_);
    return (direction_ ==kForward) ? iter_->value() : saved_value_;
  }

  virtual Status status() const {
    if (status_.ok()) returniter_->status();
    return status_;
  }
14.4.2 辅助函数
在分析seek系函数之前,先来理解两个重要的辅助函数:FindNextUserEntry和FindPrevUserEntry的功能和逻辑。其功能就是循环跳过下一个/前一个delete的记录,直到遇到kValueType的记录。
先来看看,函数声明为:
void DBIter::FindNextUserEntry(bool skipping, std::string* skip)
参数@skipping表明是否要跳过sequence更小的entry;
参数@skip临时存储空间,保存seek时要跳过的key;
在进入FindNextUserEntry时,iter_刚好定位在this->key(), this->value()这条记录上。下面来看函数实现:
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值