LevelDB project 1 10225501460 林子骥 10211900416 郭夏辉
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
7.0 KiB

1 month ago
1 month ago
1 month ago
1 month ago
  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. #include "db/version_edit.h"
  5. #include "db/version_set.h"
  6. #include "util/coding.h"
  7. namespace leveldb {
  8. // Tag numbers for serialized VersionEdit. These numbers are written to
  9. // disk and should not be changed.
  10. enum Tag {
  11. kComparator = 1,
  12. kLogNumber = 2,
  13. kNextFileNumber = 3,
  14. kLastSequence = 4,
  15. kCompactPointer = 5,
  16. kDeletedFile = 6,
  17. kNewFile = 7,
  18. // 8 was used for large value refs
  19. kPrevLogNumber = 9
  20. };
  21. void VersionEdit::Clear() {
  22. comparator_.clear();
  23. log_number_ = 0;
  24. prev_log_number_ = 0;
  25. last_sequence_ = 0;
  26. next_file_number_ = 0;
  27. has_comparator_ = false;
  28. has_log_number_ = false;
  29. has_prev_log_number_ = false;
  30. has_next_file_number_ = false;
  31. has_last_sequence_ = false;
  32. compact_pointers_.clear();
  33. deleted_files_.clear();
  34. new_files_.clear();
  35. }
  36. void VersionEdit::EncodeTo(std::string* dst) const {
  37. if (has_comparator_) {
  38. PutVarint32(dst, kComparator);
  39. PutLengthPrefixedSlice(dst, comparator_);
  40. }
  41. if (has_log_number_) {
  42. PutVarint32(dst, kLogNumber);
  43. PutVarint64(dst, log_number_);
  44. }
  45. if (has_prev_log_number_) {
  46. PutVarint32(dst, kPrevLogNumber);
  47. PutVarint64(dst, prev_log_number_);
  48. }
  49. if (has_next_file_number_) {
  50. PutVarint32(dst, kNextFileNumber);
  51. PutVarint64(dst, next_file_number_);
  52. }
  53. if (has_last_sequence_) {
  54. PutVarint32(dst, kLastSequence);
  55. PutVarint64(dst, last_sequence_);
  56. }
  57. for (size_t i = 0; i < compact_pointers_.size(); i++) {
  58. PutVarint32(dst, kCompactPointer);
  59. PutVarint32(dst, compact_pointers_[i].first); // level
  60. PutLengthPrefixedSlice(dst, compact_pointers_[i].second.Encode());
  61. }
  62. for (const auto& deleted_file_kvp : deleted_files_) {
  63. PutVarint32(dst, kDeletedFile);
  64. PutVarint32(dst, deleted_file_kvp.first); // level
  65. PutVarint64(dst, deleted_file_kvp.second); // file number
  66. }
  67. for (size_t i = 0; i < new_files_.size(); i++) {
  68. const FileMetaData& f = new_files_[i].second;
  69. PutVarint32(dst, kNewFile);
  70. PutVarint32(dst, new_files_[i].first); // level
  71. PutVarint64(dst, f.number);
  72. PutVarint64(dst, f.file_size);
  73. PutLengthPrefixedSlice(dst, f.smallest.Encode());
  74. PutLengthPrefixedSlice(dst, f.largest.Encode());
  75. PutFixed64(dst,f.oldest_ts);
  76. PutFixed64(dst,f.newer_ts);
  77. }
  78. }
  79. static bool GetInternalKey(Slice* input, InternalKey* dst) {
  80. Slice str;
  81. if (GetLengthPrefixedSlice(input, &str)) {
  82. return dst->DecodeFrom(str);
  83. } else {
  84. return false;
  85. }
  86. }
  87. static bool GetLevel(Slice* input, int* level) {
  88. uint32_t v;
  89. if (GetVarint32(input, &v) && v < config::kNumLevels) {
  90. *level = v;
  91. return true;
  92. } else {
  93. return false;
  94. }
  95. }
  96. Status VersionEdit::DecodeFrom(const Slice& src) {
  97. Clear();
  98. Slice input = src;
  99. const char* msg = nullptr;
  100. uint32_t tag;
  101. // Temporary storage for parsing
  102. int level;
  103. uint64_t number;
  104. FileMetaData f;
  105. Slice str;
  106. InternalKey key;
  107. while (msg == nullptr && GetVarint32(&input, &tag)) {
  108. switch (tag) {
  109. case kComparator:
  110. if (GetLengthPrefixedSlice(&input, &str)) {
  111. comparator_ = str.ToString();
  112. has_comparator_ = true;
  113. } else {
  114. msg = "comparator name";
  115. }
  116. break;
  117. case kLogNumber:
  118. if (GetVarint64(&input, &log_number_)) {
  119. has_log_number_ = true;
  120. } else {
  121. msg = "log number";
  122. }
  123. break;
  124. case kPrevLogNumber:
  125. if (GetVarint64(&input, &prev_log_number_)) {
  126. has_prev_log_number_ = true;
  127. } else {
  128. msg = "previous log number";
  129. }
  130. break;
  131. case kNextFileNumber:
  132. if (GetVarint64(&input, &next_file_number_)) {
  133. has_next_file_number_ = true;
  134. } else {
  135. msg = "next file number";
  136. }
  137. break;
  138. case kLastSequence:
  139. if (GetVarint64(&input, &last_sequence_)) {
  140. has_last_sequence_ = true;
  141. } else {
  142. msg = "last sequence number";
  143. }
  144. break;
  145. case kCompactPointer:
  146. if (GetLevel(&input, &level) && GetInternalKey(&input, &key)) {
  147. compact_pointers_.push_back(std::make_pair(level, key));
  148. } else {
  149. msg = "compaction pointer";
  150. }
  151. break;
  152. case kDeletedFile:
  153. if (GetLevel(&input, &level) && GetVarint64(&input, &number)) {
  154. deleted_files_.insert(std::make_pair(level, number));
  155. } else {
  156. msg = "deleted file";
  157. }
  158. break;
  159. case kNewFile:
  160. if (GetLevel(&input, &level) && GetVarint64(&input, &f.number) &&
  161. GetVarint64(&input, &f.file_size) &&
  162. GetInternalKey(&input, &f.smallest) &&
  163. GetInternalKey(&input, &f.largest)) {
  164. f.newer_ts = DecodeFixed64(input.data());
  165. f.oldest_ts = DecodeFixed64(input.data() + kTSLength);
  166. input.remove_prefix(2 * kTSLength);
  167. new_files_.push_back(std::make_pair(level, f));
  168. } else {
  169. msg = "new-file entry";
  170. }
  171. break;
  172. default:
  173. msg = "unknown tag";
  174. break;
  175. }
  176. }
  177. if (msg == nullptr && !input.empty()) {
  178. msg = "invalid tag";
  179. }
  180. Status result;
  181. if (msg != nullptr) {
  182. result = Status::Corruption("VersionEdit", msg);
  183. }
  184. return result;
  185. }
  186. std::string VersionEdit::DebugString() const {
  187. std::string r;
  188. r.append("VersionEdit {");
  189. if (has_comparator_) {
  190. r.append("\n Comparator: ");
  191. r.append(comparator_);
  192. }
  193. if (has_log_number_) {
  194. r.append("\n LogNumber: ");
  195. AppendNumberTo(&r, log_number_);
  196. }
  197. if (has_prev_log_number_) {
  198. r.append("\n PrevLogNumber: ");
  199. AppendNumberTo(&r, prev_log_number_);
  200. }
  201. if (has_next_file_number_) {
  202. r.append("\n NextFile: ");
  203. AppendNumberTo(&r, next_file_number_);
  204. }
  205. if (has_last_sequence_) {
  206. r.append("\n LastSeq: ");
  207. AppendNumberTo(&r, last_sequence_);
  208. }
  209. for (size_t i = 0; i < compact_pointers_.size(); i++) {
  210. r.append("\n CompactPointer: ");
  211. AppendNumberTo(&r, compact_pointers_[i].first);
  212. r.append(" ");
  213. r.append(compact_pointers_[i].second.DebugString());
  214. }
  215. for (const auto& deleted_files_kvp : deleted_files_) {
  216. r.append("\n RemoveFile: ");
  217. AppendNumberTo(&r, deleted_files_kvp.first);
  218. r.append(" ");
  219. AppendNumberTo(&r, deleted_files_kvp.second);
  220. }
  221. for (size_t i = 0; i < new_files_.size(); i++) {
  222. const FileMetaData& f = new_files_[i].second;
  223. r.append("\n AddFile: ");
  224. AppendNumberTo(&r, new_files_[i].first);
  225. r.append(" ");
  226. AppendNumberTo(&r, f.number);
  227. r.append(" ");
  228. AppendNumberTo(&r, f.file_size);
  229. r.append(" ");
  230. r.append(f.smallest.DebugString());
  231. r.append(" .. ");
  232. r.append(f.largest.DebugString());
  233. r.append(" ");
  234. AppendNumberTo(&r,f.oldest_ts);
  235. r.append("..");
  236. AppendNumberTo(&r,f.newer_ts);
  237. }
  238. r.append("\n}\n");
  239. return r;
  240. }
  241. } // namespace leveldb