dbformat.cc 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #include "db/dbformat.h"
  10. #include <stdio.h>
  11. #include <cinttypes>
  12. #include "monitoring/perf_context_imp.h"
  13. #include "port/port.h"
  14. #include "util/coding.h"
  15. #include "util/string_util.h"
  16. namespace ROCKSDB_NAMESPACE {
  17. // kValueTypeForSeek defines the ValueType that should be passed when
  18. // constructing a ParsedInternalKey object for seeking to a particular
  19. // sequence number (since we sort sequence numbers in decreasing order
  20. // and the value type is embedded as the low 8 bits in the sequence
  21. // number in internal keys, we need to use the highest-numbered
  22. // ValueType, not the lowest).
  23. const ValueType kValueTypeForSeek = kTypeBlobIndex;
  24. const ValueType kValueTypeForSeekForPrev = kTypeDeletion;
  25. uint64_t PackSequenceAndType(uint64_t seq, ValueType t) {
  26. assert(seq <= kMaxSequenceNumber);
  27. assert(IsExtendedValueType(t));
  28. return (seq << 8) | t;
  29. }
  30. EntryType GetEntryType(ValueType value_type) {
  31. switch (value_type) {
  32. case kTypeValue:
  33. return kEntryPut;
  34. case kTypeDeletion:
  35. return kEntryDelete;
  36. case kTypeSingleDeletion:
  37. return kEntrySingleDelete;
  38. case kTypeMerge:
  39. return kEntryMerge;
  40. case kTypeRangeDeletion:
  41. return kEntryRangeDeletion;
  42. case kTypeBlobIndex:
  43. return kEntryBlobIndex;
  44. default:
  45. return kEntryOther;
  46. }
  47. }
  48. bool ParseFullKey(const Slice& internal_key, FullKey* fkey) {
  49. ParsedInternalKey ikey;
  50. if (!ParseInternalKey(internal_key, &ikey)) {
  51. return false;
  52. }
  53. fkey->user_key = ikey.user_key;
  54. fkey->sequence = ikey.sequence;
  55. fkey->type = GetEntryType(ikey.type);
  56. return true;
  57. }
  58. void UnPackSequenceAndType(uint64_t packed, uint64_t* seq, ValueType* t) {
  59. *seq = packed >> 8;
  60. *t = static_cast<ValueType>(packed & 0xff);
  61. assert(*seq <= kMaxSequenceNumber);
  62. assert(IsExtendedValueType(*t));
  63. }
  64. void AppendInternalKey(std::string* result, const ParsedInternalKey& key) {
  65. result->append(key.user_key.data(), key.user_key.size());
  66. PutFixed64(result, PackSequenceAndType(key.sequence, key.type));
  67. }
  68. void AppendInternalKeyFooter(std::string* result, SequenceNumber s,
  69. ValueType t) {
  70. PutFixed64(result, PackSequenceAndType(s, t));
  71. }
  72. std::string ParsedInternalKey::DebugString(bool hex) const {
  73. char buf[50];
  74. snprintf(buf, sizeof(buf), "' seq:%" PRIu64 ", type:%d", sequence,
  75. static_cast<int>(type));
  76. std::string result = "'";
  77. result += user_key.ToString(hex);
  78. result += buf;
  79. return result;
  80. }
  81. std::string InternalKey::DebugString(bool hex) const {
  82. std::string result;
  83. ParsedInternalKey parsed;
  84. if (ParseInternalKey(rep_, &parsed)) {
  85. result = parsed.DebugString(hex);
  86. } else {
  87. result = "(bad)";
  88. result.append(EscapeString(rep_));
  89. }
  90. return result;
  91. }
  92. const char* InternalKeyComparator::Name() const { return name_.c_str(); }
  93. int InternalKeyComparator::Compare(const ParsedInternalKey& a,
  94. const ParsedInternalKey& b) const {
  95. // Order by:
  96. // increasing user key (according to user-supplied comparator)
  97. // decreasing sequence number
  98. // decreasing type (though sequence# should be enough to disambiguate)
  99. int r = user_comparator_.Compare(a.user_key, b.user_key);
  100. if (r == 0) {
  101. if (a.sequence > b.sequence) {
  102. r = -1;
  103. } else if (a.sequence < b.sequence) {
  104. r = +1;
  105. } else if (a.type > b.type) {
  106. r = -1;
  107. } else if (a.type < b.type) {
  108. r = +1;
  109. }
  110. }
  111. return r;
  112. }
  113. void InternalKeyComparator::FindShortestSeparator(std::string* start,
  114. const Slice& limit) const {
  115. // Attempt to shorten the user portion of the key
  116. Slice user_start = ExtractUserKey(*start);
  117. Slice user_limit = ExtractUserKey(limit);
  118. std::string tmp(user_start.data(), user_start.size());
  119. user_comparator_.FindShortestSeparator(&tmp, user_limit);
  120. if (tmp.size() <= user_start.size() &&
  121. user_comparator_.Compare(user_start, tmp) < 0) {
  122. // User key has become shorter physically, but larger logically.
  123. // Tack on the earliest possible number to the shortened user key.
  124. PutFixed64(&tmp,
  125. PackSequenceAndType(kMaxSequenceNumber, kValueTypeForSeek));
  126. assert(this->Compare(*start, tmp) < 0);
  127. assert(this->Compare(tmp, limit) < 0);
  128. start->swap(tmp);
  129. }
  130. }
  131. void InternalKeyComparator::FindShortSuccessor(std::string* key) const {
  132. Slice user_key = ExtractUserKey(*key);
  133. std::string tmp(user_key.data(), user_key.size());
  134. user_comparator_.FindShortSuccessor(&tmp);
  135. if (tmp.size() <= user_key.size() &&
  136. user_comparator_.Compare(user_key, tmp) < 0) {
  137. // User key has become shorter physically, but larger logically.
  138. // Tack on the earliest possible number to the shortened user key.
  139. PutFixed64(&tmp,
  140. PackSequenceAndType(kMaxSequenceNumber, kValueTypeForSeek));
  141. assert(this->Compare(*key, tmp) < 0);
  142. key->swap(tmp);
  143. }
  144. }
  145. LookupKey::LookupKey(const Slice& _user_key, SequenceNumber s,
  146. const Slice* ts) {
  147. size_t usize = _user_key.size();
  148. size_t ts_sz = (nullptr == ts) ? 0 : ts->size();
  149. size_t needed = usize + ts_sz + 13; // A conservative estimate
  150. char* dst;
  151. if (needed <= sizeof(space_)) {
  152. dst = space_;
  153. } else {
  154. dst = new char[needed];
  155. }
  156. start_ = dst;
  157. // NOTE: We don't support users keys of more than 2GB :)
  158. dst = EncodeVarint32(dst, static_cast<uint32_t>(usize + ts_sz + 8));
  159. kstart_ = dst;
  160. memcpy(dst, _user_key.data(), usize);
  161. dst += usize;
  162. if (nullptr != ts) {
  163. memcpy(dst, ts->data(), ts_sz);
  164. dst += ts_sz;
  165. }
  166. EncodeFixed64(dst, PackSequenceAndType(s, kValueTypeForSeek));
  167. dst += 8;
  168. end_ = dst;
  169. }
  170. void IterKey::EnlargeBuffer(size_t key_size) {
  171. // If size is smaller than buffer size, continue using current buffer,
  172. // or the static allocated one, as default
  173. assert(key_size > buf_size_);
  174. // Need to enlarge the buffer.
  175. ResetBuffer();
  176. buf_ = new char[key_size];
  177. buf_size_ = key_size;
  178. }
  179. } // namespace ROCKSDB_NAMESPACE