user key
即用户传入的key
InternalKey
组成:
| user_key | 56位sequence_number+8位type(fixed64) |
|---|
LookupKey
即memtable key,去MemTable做Get操作,使用LookupKey,由user key和snapshot(或者last sequence number)生成
成员:
class LookupKey {
// 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_; // key起点,start_到kstart_是Varint32编码的(user_key长度+8)字节数
const char* kstart_; // user key , sequence+type(8字节) 到end_(internal key)
const char* end_;
char space_[200]; // 避免频繁分配内存,start_为起点的内存分配,短key复用space_, 长key直接在堆上分配
其中klength使用varint32编码,编码内容为user_key的长度+8个字节(fixed64),其中这个fixed64编码了sequence number + type的值,这个值的组成:
- sequence number << 56 |(seek type,枚举值为0x01)
- sequence number为snapshot或者last sequence number,最大不超过56位;seek type为8位值为0x01
有关type类型:
enum ValueType { kTypeDeletion = 0x0, kTypeValue = 0x1 };
static const ValueType kValueTypeForSeek = kTypeValue;
memtable的Get操作查找key使用的比较器internal_comparator_为用户传入raw_options.comparator
Comparators
Comparator
InternalKeyComparator
internalkey的比较器实现
internal key的比较
// 先比较user key,这个是用户自定义的,升序
// 如果相等, 则比较sequence+type,降序
// 返回值:<0 a.user_key < b.user_key
// >0 a.user_key > b.user_key
// -1 a.sequence_type > b.sequence_type, user_key相等
// 1 a.sequence_type < b.sequence_type, user_key相等
int InternalKeyComparator::Compare(const Slice& akey, const Slice& bkey) const {
// Order by:
// increasing user key (according to user-supplied comparator)
// decreasing sequence number
// decreasing type (though sequence# should be enough to disambiguate)
int r = user_comparator_->Compare(ExtractUserKey(akey), ExtractUserKey(bkey));
if (r == 0) {
const uint64_t anum = DecodeFixed64(akey.data() + akey.size() - 8); // char* = char* + size_t - 8
const uint64_t bnum = DecodeFixed64(bkey.data() + bkey.size() - 8); // 获取sequence+type的编码
if (anum > bnum) {
r = -1;
} else if (anum < bnum) {
r = +1;
}
}
return r;
}
user key按升序排列,sequence+type按降序
各种key使用场景
user key:
user key即用户传入的key,某些场景会用于查找过程的比较
internal key:
get请求处理,查找memtable,输入internal key,依次比较user_key、sequence_type
文件smallest/largest都是internal key
memtable key:
memtable存储使用的是memtable key,这里是用memtable key主要是为了方便获取char*类型的internal key字符串;