leveldb深度剖析-存储流程(2)

继续上一篇内容,本篇继续说明leveldb是如何将数据插入到MemTable中。

一、Iterate循环处理

插入到MemTable使用该接口WriteBatchInternal::InsertInto,具体实现是:

Status WriteBatchInternal::InsertInto(const WriteBatch* b,
                                      MemTable* memtable) {
  //初始化 Handler 
  MemTableInserter inserter;
  inserter.sequence_ = WriteBatchInternal::Sequence(b);//获取序号
  inserter.mem_ = memtable;
  return b->Iterate(&inserter);
}

在WriteBatch中可能存在多个key-value对,所以在WriteBatch类中提供了一个迭代器方法Iterate,具体实现如下:

/**
 * 将key-value一个一个存储到Memtable中
 * @param handler 真正执行存储操作
 * 特别说明:
 *     rep_是数据保存地方,格式为seq number|count|key-value|...|key-value
 *     Iterate方法主要工作是将一个一个key-value对解析出来 插入到Memtable中
 */
Status WriteBatch::Iterate(Handler* handler) const {
  Slice input(rep_);
  if (input.size() < kHeader) {
    return Status::Corruption("malformed WriteBatch (too small)");
  }

  input.remove_prefix(kHeader);//跳过头部信息 seq number | count
  Slice key, value;
  int found = 0;
  while (!input.empty()) {
    found++;
    char tag = input[0]; // 获取type
    input.remove_prefix(1);
    switch (tag) {
      case kTypeValue://添加操作
        if (GetLengthPrefixedSlice(&input, &key) &&
            GetLengthPrefixedSlice(&input, &value)) {//解析出key - value
          handler->Put(key, value);// MemTableInserter  此处的key value就是用输入的key和value
        } else {
          return Status::Corruption("bad WriteBatch Put");
        }
        break;
      case kTypeDeletion://删除操作
        if (GetLengthPrefixedSlice(&input, &key)) {
          handler->Delete(key);//这里key为用户输入key
        } else {
          return Status::Corruption("bad WriteBatch Delete");
        }
        break;
      default:
        return Status::Corruption("unknown WriteBatch tag");
    }
  }

  //最后再次判断是否已经完全处理完
  if (found != WriteBatchInternal::Count(this)) {
    return Status::Corruption("WriteBatch has wrong count");
  } else {
    return Status::OK();
  }
}

通过上面代码可知,调用handler中的Put和Delete方法进行插入和删除。通过上面可知handler实际为MemTableInserter,下面是Put和Delete实现,比较简单:

  virtual void Put(const Slice& key, const Slice& value) {
    mem_->Add(sequence_, kTypeValue, key, value);
    sequence_++;
  }

  /**
   * Memtable只有插入操作 并没有真正删除操作   
   */
  virtual void Delete(const Slice& key) {
    mem_->Add(sequence_, kTypeDeletion, key, Slice());// value是空字符串
    sequence_++;
  }

这里需要强调一下:

1) 这里的key/value是用户输入的key/value,后面在MemTable中leveldb会对其再次封装成InternalKey。

2) 这里的sequence_ 是独立计数器。

二、MemTable插入操作

对于MemTable插入流程可参考本篇《leveldb深度剖析-MemTable》。当MemTable占用内存空间超过4M就会将MemTable中数据flush到level0文件中,下一篇将介绍是如何写入到level0中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值