leveldb数据的插入-跳表
本文主要是接着上一篇文章,继续深入探索Write函数调用插入之后的流程。
status = WriteBatchInternal::InsertInto(updates, mem_);
InsertInto插入数据函数
namespace {
class MemTableInserter : public WriteBatch::Handler { // MemTable插入类
public:
SequenceNumber sequence_;
MemTable* mem_;
void Put(const Slice& key, const Slice& value) override { // 添加内容
mem_->Add(sequence_, kTypeValue, key, value); // 添加序列号 插入类型 key value
sequence_++;
}
void Delete(const Slice& key) override {
mem_->Add(sequence_, kTypeDeletion, key, Slice()); // 添加内容 序列号 删除类型 key 空的value
sequence_++;
}
};
} // namespace
Status WriteBatchInternal::InsertInto(const WriteBatch* b, MemTable* memtable) {
MemTableInserter inserter;
inserter.sequence_ = WriteBatchInternal::Sequence(b); // 先获取序列号
inserter.mem_ = memtable; // 设置memtabe
return b->Iterate(&inserter); // 迭代插入
}
可以得知,真正的插入数据的操作是在调用InsertInto函数,将序列化好的数据设置到inserter的sequence_属性中,传入当前的memtable,此时就调用WriteBatch的Iterate方法,来插入数据。
Status WriteBatch::Iterate(Handler* handler) const { // 迭代器
Slice input(rep_);
if (input.size() < kHeader) { // 如果输入的大小小于头部信息的大小 则太小了
return Status::Corruption("malformed WriteBatch (too small)");
}
input.remove_prefix(kHeader); // 移除头部
Slice key, value;
int found = 0;
while (!input.empty()) { // 检查是否为空
found++;
char tag = input[0]; // 获取当前的tag
input.remove_prefix(1); // 移除一个该位
switch (tag) { // 检查该tag是Put还是Delete
case kTypeValue: // 如果是添加
if (GetLengthPrefixedSlice(&input, &key) &&
GetLengthPrefixedSlice(&input, &value)) { // 分别获取key 和 value
handler->Put(key, value); // 调用handler去添加
} else {
return Status::Corruption("bad WriteBatch Put");
}
break;
case kTypeDeletion: // 如果是删除