memtable.cc
1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 5 #include "db/memtable.h" 6 #include "db/dbformat.h" 7 #include "leveldb/comparator.h" 8 #include "leveldb/env.h" 9 #include "leveldb/iterator.h" 10 #include "util/coding.h" 11 12 namespace leveldb { 13 14 static Slice GetLengthPrefixedSlice(const char* data) { 15 uint32_t len; 16 const char* p = data; 17 p = GetVarint32Ptr(p, p + 5, &len); // +5: we assume "p" is not corrupted 18 return Slice(p, len); 19 } 20 21 MemTable::MemTable(const InternalKeyComparator& comparator) 22 : comparator_(comparator), refs_(0), table_(comparator_, &arena_) {} 23 24 MemTable::~MemTable() { assert(refs_ == 0); } 25 26 size_t MemTable::ApproximateMemoryUsage() { return arena_.MemoryUsage(); } 27 28 int MemTable::KeyComparator::operator()(const char* aptr, 29 const char* bptr) const { 30 // Internal keys are encoded as length-prefixed strings. 31 Slice a = GetLengthPrefixedSlice(aptr); 32 Slice b = GetLengthPrefixedSlice(bptr); 33 return comparator.Compare(a, b); 34 } 35 36 // Encode a suitable internal key target for "target" and return it. 37 // Uses *scratch as scratch space, and the returned pointer will point 38 // into this scratch space. 39 static const char* EncodeKey(std::string* scratch, const Slice& target) { 40 scratch->clear(); 41 PutVarint32(scratch, target.size()); 42 scratch->append(target.data(), target.size()); 43 return scratch->data(); 44 } 45 46 class MemTableIterator : public Iterator { 47 public: 48 explicit MemTableIterator(MemTable::Table* table) : iter_(table) {} 49 50 MemTableIterator(const MemTableIterator&) = delete; 51 MemTableIterator& operator=(const MemTableIterator&) = delete; 52 53 ~MemTableIterator() override = default; 54 55 bool Valid() const override { return iter_.Valid(); } 56 void Seek(const Slice& k) override { iter_.Seek(EncodeKey(&tmp_, k)); } 57 void SeekToFirst() override { iter_.SeekToFirst(); } 58 void SeekToLast() override { iter_.SeekToLast(); } 59 void Next() override { iter_.Next(); } 60 void Prev() override { iter_.Prev(); } 61 Slice key() const override { return GetLengthPrefixedSlice(iter_.key()); } 62 Slice value() const override { 63 Slice key_slice = GetLengthPrefixedSlice(iter_.key()); 64 return GetLengthPrefixedSlice(key_slice.data() + key_slice.size()); 65 } 66 67 Status status() const override { return Status::OK(); } 68 69 private: 70 MemTable::Table::Iterator iter_; 71 std::string tmp_; // For passing to EncodeKey 72 }; 73 74 Iterator* MemTable::NewIterator() { return new MemTableIterator(&table_); } 75 76 void MemTable::Add(SequenceNumber s, ValueType type, const Slice& key, 77 const Slice& value) { 78 // Format of an entry is concatenation of: 79 // key_size : varint32 of internal_key.size() 80 // key bytes : char[internal_key.size()] 81 // value_size : varint32 of value.size() 82 // value bytes : char[value.size()] 83 size_t key_size = key.size(); 84 size_t val_size = value.size(); 85 size_t internal_key_size = key_size + 8; 86 const size_t encoded_len = VarintLength(internal_key_size) + 87 internal_key_size + VarintLength(val_size) + 88 val_size; 89 char* buf = arena_.Allocate(encoded_len); 90 char* p = EncodeVarint32(buf, internal_key_size); 91 memcpy(p, key.data(), key_size); 92 p += key_size; 93 EncodeFixed64(p, (s << 8) | type); 94 p += 8; 95 p = EncodeVarint32(p, val_size); 96 memcpy(p, value.data(), val_size); 97 assert(p + val_size == buf + encoded_len); 98 table_.Insert(buf); 99 } 100 101 bool MemTable::Get(const LookupKey& key, std::string* value, Status* s) { 102 Slice memkey = key.memtable_key(); 103 Table::Iterator iter(&table_); 104 iter.Seek(memkey.data()); 105 if (iter.Valid()) { 106 // entry format is: 107 // klength varint32 108 // userkey char[klength] 109 // tag uint64 110 // vlength varint32 111 // value char[vlength] 112 // Check that it belongs to same user key. We do not check the 113 // sequence number since the Seek() call above should have skipped 114 // all entries with overly large sequence numbers. 115 const char* entry = iter.key(); 116 uint32_t key_length; 117 const char* key_ptr = GetVarint32Ptr(entry, entry + 5, &key_length); 118 if (comparator_.comparator.user_comparator()->Compare( 119 Slice(key_ptr, key_length - 8), key.user_key()) == 0) { 120 // Correct user key 121 const uint64_t tag = DecodeFixed64(key_ptr + key_length - 8); 122 switch (static_cast<ValueType>(tag & 0xff)) { 123 case kTypeValue: { 124 Slice v = GetLengthPrefixedSlice(key_ptr + key_length); 125 value->assign(v.data(), v.size()); 126 return true; 127 } 128 case kTypeDeletion: 129 *s = Status::NotFound(Slice()); 130 return true; 131 } 132 } 133 } 134 return false; 135 } 136 137 } // namespace leveldb