User Key
我們先從最底層開始看起,User key就是用戶所傳入的鍵值數據
Slice user_key
ParsedInternalKey&InternalKey
InternalKey的格式為: | User key (string) | sequence number (7 bytes) | value type (1 byte) |
// ValueType代表這個數據是要插入還是刪除,0就刪除,1就保留
enum ValueType {
kTypeDeletion = 0x0,
kTypeValue = 0x1
};
// kValueTypeForSeek defines the ValueType that should be passed when
// constructing a ParsedInternalKey object for seeking to a particular
// sequence number (since we sort sequence numbers in decreasing order
// and the value type is embedded as the low 8 bits in the sequence
// number in internal keys, we need to use the highest-numbered
// ValueType, not the lowest).
static const ValueType kValueTypeForSeek = kTypeValue;
typedef uint64_t SequenceNumber;
// We leave eight bits empty at the bottom so a type and sequence#
// can be packed together into 64-bits.
// 這裡定義SequenceNum可以取值的範圍[0,2^56-1)
static const SequenceNumber kMaxSequenceNumber =
((0x1ull << 56) - 1);
// ParsedInternalKey則是將InternalKey分拆的結果,由user_key,sequenceNum,type組成
struct ParsedInternalKey {
Slice user_key;
SequenceNumber sequence;
ValueType type;
ParsedInternalKey() { } // Intentionally left uninitialized (for speed)
ParsedInternalKey(const Slice& u, const SequenceNumber& seq, ValueType t)
: user_key(u), sequence(seq), type(t) { }
std::string DebugString() const;
};
// Return the length of the encoding of "key".
// 因為InternalKey是user_Key,sequenceNum,type組成,因為sequenceNum和type共64bit,
// 也就是8bytes,所以長度就是user_key+8
inline size_t InternalKeyEncodingLength(const ParsedInternalKey& key) {
return key.user_key.size() + 8;
}
LookupKey & Memtable Key
| Size (varint32)| User key (string) | sequence number (7 bytes) | value type (1 byte) |
- start_為字串的開始地址
- end_為字串的結束地址
- kstart_紀錄user_key的起始地址
*LookupKey的size是變長存儲的,因此它使用kstart_記錄了user key string的起始地址,否則將不能正確的獲取size和user key;
class LookupKey {
public:
// Initialize *this for looking up user_key at a snapshot with
// the specified sequence number.
LookupKey(const Slice& user_key, SequenceNumber sequence);
~LookupKey();
// Return a key suitable for lookup in a MemTable.
// 從下方得知LookupKey為 Memtable Key 的 Slice 形式
Slice memtable_key() const { return Slice(start_, end_ - start_); }
// Return an internal key (suitable for passing to an internal iterator)
// 因為internalkey為user_key+sequenceNum+type,所以是 Slice(kstart_, end_-kstart_)
Slice internal_key() const { return Slice(kstart_, end_ - kstart_); }
// Return the user key
// user_key就是再扣掉sequenceNum跟type所以是8
Slice user_key() const { return Slice(kstart_, end_ - kstart_ - 8); }
private:
// We construct a char array of the form:
// klength varint32 <-- start_
// userkey char[klength] <-- kstart_
// tag uint64
// <-- end_
// The array is a suitable MemTable key.
// The suffix starting with "userkey" can be used as an InternalKey.
const char* start_;
const char* kstart_;
const char* end_;
下方為LookupKey的實作
LookupKey::LookupKey(const Slice& user_key, SequenceNumber s) {
size_t usize = user_key.size();// user_key長度
size_t needed = usize + 13; // A conservative estimate
// +13是 sequenceNum+type=8 和 varint32最大為5bytes
char* dst;
if (needed <= sizeof(space_)) {
dst = space_;
} else {
dst = new char[needed];//若超過預留得space_就要重新分配
}
//下方為計算start_,kstart_,end_的實作
start_ = dst;
dst = EncodeVarint32(dst, usize + 8);
kstart_ = dst;
memcpy(dst, user_key.data(), usize);
dst += usize;
EncodeFixed64(dst, PackSequenceAndType(s, kValueTypeForSeek));
dst += 8;
end_ = dst;
}
沒有留言:
張貼留言