[leveldb]key总结

438 阅读1分钟

user key

即用户传入的key

InternalKey

组成:

user_key56位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直接在堆上分配

屏幕快照 2022-04-28 下午2.49.03.png

其中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字符串;