2018年6月13日 星期三

Google LevelDB 原始碼解說 (四) Memtable Add&Get

Memtable有屬於自己的add和get,Immutable Memtable也大同小異,這邊對Memtable add&get的實作做說明,實作內容在 Memtable.cc




Add

這裡的內部格式為
| internal_key size | key_data | squence+type | value_size | value_data |
                                       (Internal key)         




  1. void MemTable::Add(SequenceNumber s, ValueType type,
  2. const Slice& key,
  3. const Slice& value) {
  4. // Format of an entry is concatenation of:
  5. // key_size : varint32 of internal_key.size()
  6. // key bytes : char[internal_key.size()]
  7. // value_size : varint32 of value.size()
  8. // value bytes : char[value.size()]
  9. size_t key_size = key.size();
  10. size_t val_size = value.size();
  11. //前篇文章有說 internal key = key+seq+type
  12. size_t internal_key_size = key_size + 8;
  13. //skiplist內部格式
  14. const size_t encoded_len =
  15. VarintLength(internal_key_size) + internal_key_size +
  16. VarintLength(val_size) + val_size;
  17. //分配記憶體到buf中
  18. char* buf = arena_.Allocate(encoded_len);
  19. //儲存internal_key_size到buf中,之後會再詳細解釋Encode相關文章
  20. char* p = EncodeVarint32(buf, internal_key_size);
  21. //將key.data存入
  22. memcpy(p, key.data(), key_size);
  23. //將指標移到sequence num前
  24. p += key_size;
  25. //將sequence+num 打包存入p(buf)中
  26. EncodeFixed64(p, (s << 8) | type);
  27. //將指標移到儲存value地址之前
  28. p += 8;
  29. //儲存value size
  30. p = EncodeVarint32(p, val_size);
  31. //儲存value的值
  32. memcpy(p, value.data(), val_size);
  33. assert(p + val_size == buf + encoded_len);
  34. //將整條結構存入skiplist中
  35. table_.Insert(buf);
  36. }

Get


  1. bool MemTable::Get(const LookupKey& key, std::string* value, Status* s) {
  2. Slice memkey = key.memtable_key();
  1. //從skiplist中尋找key值
  2. Table::Iterator iter(&table_);
  3. iter.Seek(memkey.data());
  4. if (iter.Valid()) {
  5. // entry format is:
  6. // klength varint32
  7. // userkey char[klength]
  8. // tag uint64
  9. // vlength varint32
  10. // value char[vlength]
  11. // Check that it belongs to same user key. We do not check the
  12. // sequence number since the Seek() call above should have skipped
  13. // all entries with overly large sequence numbers.
  14. const char* entry = iter.key();
  15. uint32_t key_length;
  16. //通過以下語句獲取internal key size,因為varint最大為5,所以長度為entry到entry+5
  17. const char* key_ptr = GetVarint32Ptr(entry, entry+5, &key_length);
  18. //比較返回的key與user_key是否相同,key_length-8是因為internal key包含了sequence numbers和type
  19. if (comparator_.comparator.user_comparator()->Compare(Slice(key_ptr, key_length - 8),key.user_key()) == 0) {
  20. // Correct user key
  21. //對key解碼
  22. const uint64_t tag = DecodeFixed64(key_ptr + key_length - 8);
  23. //比較類型,如果不是kTypeDeletion,則獲取value的size跟value的值
  24. switch (static_cast<ValueType>(tag & 0xff)) {
  25. case kTypeValue: {
  26. Slice v = GetLengthPrefixedSlice(key_ptr + key_length);
  27. value->assign(v.data(), v.size());
  28. return true;
  29. }
  30. case kTypeDeletion:
  31. *s = Status::NotFound(Slice());
  32. return true;
  33. }
  34. }
  35. }
  36. return false;
  37. }

沒有留言:

張貼留言

熱門文章