作者: 韩晨旭 10225101440 李畅 10225102463
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.

301 lines
8.0 KiB

  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. kLargeValueRef = 8,
  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. deleted_files_.clear();
  33. new_files_.clear();
  34. large_refs_added_.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 (int 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 (DeletedFileSet::const_iterator iter = deleted_files_.begin();
  63. iter != deleted_files_.end();
  64. ++iter) {
  65. PutVarint32(dst, kDeletedFile);
  66. PutVarint32(dst, iter->first); // level
  67. PutVarint64(dst, iter->second); // file number
  68. }
  69. for (int i = 0; i < new_files_.size(); i++) {
  70. const FileMetaData& f = new_files_[i].second;
  71. PutVarint32(dst, kNewFile);
  72. PutVarint32(dst, new_files_[i].first); // level
  73. PutVarint64(dst, f.number);
  74. PutVarint64(dst, f.file_size);
  75. PutLengthPrefixedSlice(dst, f.smallest.Encode());
  76. PutLengthPrefixedSlice(dst, f.largest.Encode());
  77. }
  78. for (int i = 0; i < large_refs_added_.size(); i++) {
  79. const VersionEdit::Large& l = large_refs_added_[i];
  80. PutVarint32(dst, kLargeValueRef);
  81. PutLengthPrefixedSlice(dst,
  82. Slice(l.large_ref.data, LargeValueRef::ByteSize()));
  83. PutVarint64(dst, l.fnum);
  84. PutLengthPrefixedSlice(dst, l.internal_key.Encode());
  85. }
  86. }
  87. static bool GetInternalKey(Slice* input, InternalKey* dst) {
  88. Slice str;
  89. if (GetLengthPrefixedSlice(input, &str)) {
  90. dst->DecodeFrom(str);
  91. return true;
  92. } else {
  93. return false;
  94. }
  95. }
  96. static bool GetLevel(Slice* input, int* level) {
  97. uint32_t v;
  98. if (GetVarint32(input, &v) &&
  99. v < config::kNumLevels) {
  100. *level = v;
  101. return true;
  102. } else {
  103. return false;
  104. }
  105. }
  106. Status VersionEdit::DecodeFrom(const Slice& src) {
  107. Clear();
  108. Slice input = src;
  109. const char* msg = NULL;
  110. uint32_t tag;
  111. // Temporary storage for parsing
  112. int level;
  113. uint64_t number;
  114. FileMetaData f;
  115. Slice str;
  116. Large large;
  117. InternalKey key;
  118. while (msg == NULL && GetVarint32(&input, &tag)) {
  119. switch (tag) {
  120. case kComparator:
  121. if (GetLengthPrefixedSlice(&input, &str)) {
  122. comparator_ = str.ToString();
  123. has_comparator_ = true;
  124. } else {
  125. msg = "comparator name";
  126. }
  127. break;
  128. case kLogNumber:
  129. if (GetVarint64(&input, &log_number_)) {
  130. has_log_number_ = true;
  131. } else {
  132. msg = "log number";
  133. }
  134. break;
  135. case kPrevLogNumber:
  136. if (GetVarint64(&input, &prev_log_number_)) {
  137. has_prev_log_number_ = true;
  138. } else {
  139. msg = "previous log number";
  140. }
  141. break;
  142. case kNextFileNumber:
  143. if (GetVarint64(&input, &next_file_number_)) {
  144. has_next_file_number_ = true;
  145. } else {
  146. msg = "next file number";
  147. }
  148. break;
  149. case kLastSequence:
  150. if (GetVarint64(&input, &last_sequence_)) {
  151. has_last_sequence_ = true;
  152. } else {
  153. msg = "last sequence number";
  154. }
  155. break;
  156. case kCompactPointer:
  157. if (GetLevel(&input, &level) &&
  158. GetInternalKey(&input, &key)) {
  159. compact_pointers_.push_back(std::make_pair(level, key));
  160. } else {
  161. msg = "compaction pointer";
  162. }
  163. break;
  164. case kDeletedFile:
  165. if (GetLevel(&input, &level) &&
  166. GetVarint64(&input, &number)) {
  167. deleted_files_.insert(std::make_pair(level, number));
  168. } else {
  169. msg = "deleted file";
  170. }
  171. break;
  172. case kNewFile:
  173. if (GetLevel(&input, &level) &&
  174. GetVarint64(&input, &f.number) &&
  175. GetVarint64(&input, &f.file_size) &&
  176. GetInternalKey(&input, &f.smallest) &&
  177. GetInternalKey(&input, &f.largest)) {
  178. new_files_.push_back(std::make_pair(level, f));
  179. } else {
  180. msg = "new-file entry";
  181. }
  182. break;
  183. case kLargeValueRef:
  184. if (GetLengthPrefixedSlice(&input, &str) &&
  185. (str.size() == LargeValueRef::ByteSize()) &&
  186. GetVarint64(&input, &large.fnum) &&
  187. GetInternalKey(&input, &large.internal_key)) {
  188. large.large_ref = LargeValueRef::FromRef(str);
  189. large_refs_added_.push_back(large);
  190. } else {
  191. msg = "large ref";
  192. }
  193. break;
  194. default:
  195. msg = "unknown tag";
  196. break;
  197. }
  198. }
  199. if (msg == NULL && !input.empty()) {
  200. msg = "invalid tag";
  201. }
  202. Status result;
  203. if (msg != NULL) {
  204. result = Status::Corruption("VersionEdit", msg);
  205. }
  206. return result;
  207. }
  208. std::string VersionEdit::DebugString() const {
  209. std::string r;
  210. r.append("VersionEdit {");
  211. if (has_comparator_) {
  212. r.append("\n Comparator: ");
  213. r.append(comparator_);
  214. }
  215. if (has_log_number_) {
  216. r.append("\n LogNumber: ");
  217. AppendNumberTo(&r, log_number_);
  218. }
  219. if (has_prev_log_number_) {
  220. r.append("\n PrevLogNumber: ");
  221. AppendNumberTo(&r, prev_log_number_);
  222. }
  223. if (has_next_file_number_) {
  224. r.append("\n NextFile: ");
  225. AppendNumberTo(&r, next_file_number_);
  226. }
  227. if (has_last_sequence_) {
  228. r.append("\n LastSeq: ");
  229. AppendNumberTo(&r, last_sequence_);
  230. }
  231. for (int i = 0; i < compact_pointers_.size(); i++) {
  232. r.append("\n CompactPointer: ");
  233. AppendNumberTo(&r, compact_pointers_[i].first);
  234. r.append(" '");
  235. AppendEscapedStringTo(&r, compact_pointers_[i].second.Encode());
  236. r.append("'");
  237. }
  238. for (DeletedFileSet::const_iterator iter = deleted_files_.begin();
  239. iter != deleted_files_.end();
  240. ++iter) {
  241. r.append("\n DeleteFile: ");
  242. AppendNumberTo(&r, iter->first);
  243. r.append(" ");
  244. AppendNumberTo(&r, iter->second);
  245. }
  246. for (int i = 0; i < new_files_.size(); i++) {
  247. const FileMetaData& f = new_files_[i].second;
  248. r.append("\n AddFile: ");
  249. AppendNumberTo(&r, new_files_[i].first);
  250. r.append(" ");
  251. AppendNumberTo(&r, f.number);
  252. r.append(" ");
  253. AppendNumberTo(&r, f.file_size);
  254. r.append(" '");
  255. AppendEscapedStringTo(&r, f.smallest.Encode());
  256. r.append("' .. '");
  257. AppendEscapedStringTo(&r, f.largest.Encode());
  258. r.append("'");
  259. }
  260. for (int i = 0; i < large_refs_added_.size(); i++) {
  261. const VersionEdit::Large& l = large_refs_added_[i];
  262. r.append("\n LargeRef: ");
  263. AppendNumberTo(&r, l.fnum);
  264. r.append(" ");
  265. r.append(LargeValueRefToFilenameString(l.large_ref));
  266. r.append(" '");
  267. AppendEscapedStringTo(&r, l.internal_key.Encode());
  268. r.append("'");
  269. }
  270. r.append("\n}\n");
  271. return r;
  272. }
  273. }