时间:2021-07-01 10:21:17 帮助过:2人阅读
这段代码是让
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<ValueType>(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。
leveldb 源码阅读,细节记录memberTable
标签: