博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
leveldb 源码阅读,细节记录memberTable
阅读量:4965 次
发布时间:2019-06-12

本文共 3316 字,大约阅读时间需要 11 分钟。

leveldb 是看着前辈们的大概分析,然后看着源码,将自己的疑惑和解决记录下来:

从memberTable插入一条记录和查找一条记录从上而下分析

 

插入:

插入的函数 void MemTable::Add(SequenceNumber s, ValueType type,const Slice& key,const Slice& value)

参数:

SequenceNumber    插入的序号,在skiplist里,这个序号是降序列的

ValueType type   类型添加值还是删除值,

Slice key       就是key

value        就是value

void MemTable::Add(SequenceNumber s, ValueType type,                   const Slice& key,                   const Slice& value) {  // Format of an entry is concatenation of:  //  key_size     : varint32 of internal_key.size()  //  key bytes    : char[internal_key.size()]  //  value_size   : varint32 of value.size()  //  value bytes  : char[value.size()]  size_t key_size = key.size();  size_t val_size = value.size();  size_t internal_key_size = key_size + 8;  const size_t encoded_len =      VarintLength(internal_key_size) + internal_key_size +      VarintLength(val_size) + val_size;  char* buf = arena_.Allocate(encoded_len);  char* p = EncodeVarint32(buf, internal_key_size);  memcpy(p, key.data(), key_size);  p += key_size;  EncodeFixed64(p, (s << 8) | type);  p += 8;  p = EncodeVarint32(p, val_size);  memcpy(p, value.data(), val_size);  assert((p + val_size) - buf == encoded_len);  table_.Insert(buf);}

这段代码是让

buf=key.size()压缩存储+(key+(SequenceNumber | TypeValue))+value.size()压缩存储+value

再将buf添加到skiplist里

 

查找:MemTable::Get(const LookupKey& key, std::string* value, Status* s)

参数:

LookupKey& key    查找的key,

string* value       用于存放查找结果的value

Status* s       存储key的状态,是删除还是添加

bool MemTable::Get(const LookupKey& key, std::string* value, Status* s) {  Slice memkey = key.memtable_key();  Table::Iterator iter(&table_);  iter.Seek(memkey.data());  if (iter.Valid()) {    // entry format is:    //    klength  varint32    //    userkey  char[klength]    //    tag      uint64    //    vlength  varint32    //    value    char[vlength]    // Check that it belongs to same user key.  We do not check the    // sequence number since the Seek() call above should have skipped    // all entries with overly large sequence numbers.    const char* entry = iter.key();    uint32_t key_length;    const char* key_ptr = GetVarint32Ptr(entry, entry+5, &key_length);    if (comparator_.comparator.user_comparator()->Compare(            Slice(key_ptr, key_length - 8),            key.user_key()) == 0) {      // Correct user key      const uint64_t tag = DecodeFixed64(key_ptr + key_length - 8);      switch (static_cast
(tag & 0xff)) { case kTypeValue: { Slice v = GetLengthPrefixedSlice(key_ptr + key_length); value->assign(v.data(), v.size()); return true; } case kTypeDeletion: *s = Status::NotFound(Slice()); return true; } } } return false;}

首先需要从LookupKey里提取符合memberTable格式的key出来,因为前面存储时是按照一定格式来的,所以LookupKey.memberTable_key()返回的字符串格式是:key.size()压缩存储+(key+(SequenceNumber | TypeValue),但是为什么没有后面的那部分呢(value.size()压缩存储+value),这是因为有 InternalKeyComparator class 的存在,这个是继承Comparator class的,而且里面包含了一个comparator。InternalKeyComparator相当于一个适配器,将符合memberTable key格式的数据段将key提取出来,再用用户自定义的comparator或者预置的comparator来对真实的key进行比较。如果真实key比较结果是相同,则将(SequenceNumber| TypeValue)提取出来进行比较,真实情况下,Type不会进行比较,只是SequenceNumber进行比较,因为SequenceNumber是在SkipList 里是降序排序的,为了防止TypeValue对排序的影响,所以LookupKey里的TypeValue是0x1。

 

转载于:https://www.cnblogs.com/xuyung/p/5024307.html

你可能感兴趣的文章
SQL Server-5种常见的约束
查看>>
硬件之美
查看>>
[转载]java开发中的23种设计模式
查看>>
表格的拖拽功能
查看>>
函数的形参和实参
查看>>
文字过长 用 ... 表示 CSS实现单行、多行文本溢出显示省略号
查看>>
1Caesar加密
查看>>
【TP SRM 703 div2 500】 GCDGraph
查看>>
MapReduce 重要组件——Recordreader组件 [转]
查看>>
webdriver api
查看>>
apache 实现图标缓存客户端
查看>>
揭秘:黑客必备的Kali Linux是什么,有哪些弊端?
查看>>
linux系统的远程控制方法——学神IT教育
查看>>
springboot+mybatis报错Invalid bound statement (not found)
查看>>
Linux环境下SolrCloud集群环境搭建关键步骤
查看>>
P3565 [POI2014]HOT-Hotels
查看>>
MongoDB的简单使用
查看>>
hdfs 命令使用
查看>>
prometheus配置
查看>>
【noip2004】虫食算——剪枝DFS
查看>>