version_edit.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  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/version_edit.h"
  10. #include "db/blob_index.h"
  11. #include "db/version_set.h"
  12. #include "logging/event_logger.h"
  13. #include "rocksdb/slice.h"
  14. #include "test_util/sync_point.h"
  15. #include "util/coding.h"
  16. #include "util/string_util.h"
  17. namespace ROCKSDB_NAMESPACE {
  18. // The unknown file checksum.
  19. const std::string kUnknownFileChecksum("");
  20. // The unknown sst file checksum function name.
  21. const std::string kUnknownFileChecksumFuncName("Unknown");
  22. // Mask for an identified tag from the future which can be safely ignored.
  23. const uint32_t kTagSafeIgnoreMask = 1 << 13;
  24. // Tag numbers for serialized VersionEdit. These numbers are written to
  25. // disk and should not be changed. The number should be forward compatible so
  26. // users can down-grade RocksDB safely. A future Tag is ignored by doing '&'
  27. // between Tag and kTagSafeIgnoreMask field.
  28. enum Tag : uint32_t {
  29. kComparator = 1,
  30. kLogNumber = 2,
  31. kNextFileNumber = 3,
  32. kLastSequence = 4,
  33. kCompactPointer = 5,
  34. kDeletedFile = 6,
  35. kNewFile = 7,
  36. // 8 was used for large value refs
  37. kPrevLogNumber = 9,
  38. kMinLogNumberToKeep = 10,
  39. // Ignore-able field
  40. kDbId = kTagSafeIgnoreMask + 1,
  41. // these are new formats divergent from open source leveldb
  42. kNewFile2 = 100,
  43. kNewFile3 = 102,
  44. kNewFile4 = 103, // 4th (the latest) format version of adding files
  45. kColumnFamily = 200, // specify column family for version edit
  46. kColumnFamilyAdd = 201,
  47. kColumnFamilyDrop = 202,
  48. kMaxColumnFamily = 203,
  49. kInAtomicGroup = 300,
  50. };
  51. enum CustomTag : uint32_t {
  52. kTerminate = 1, // The end of customized fields
  53. kNeedCompaction = 2,
  54. // Since Manifest is not entirely currently forward-compatible, and the only
  55. // forward-compatible part is the CutsomtTag of kNewFile, we currently encode
  56. // kMinLogNumberToKeep as part of a CustomTag as a hack. This should be
  57. // removed when manifest becomes forward-comptabile.
  58. kMinLogNumberToKeepHack = 3,
  59. kOldestBlobFileNumber = 4,
  60. kOldestAncesterTime = 5,
  61. kFileCreationTime = 6,
  62. kFileChecksum = 7,
  63. kFileChecksumFuncName = 8,
  64. kPathId = 65,
  65. };
  66. // If this bit for the custom tag is set, opening DB should fail if
  67. // we don't know this field.
  68. uint32_t kCustomTagNonSafeIgnoreMask = 1 << 6;
  69. uint64_t PackFileNumberAndPathId(uint64_t number, uint64_t path_id) {
  70. assert(number <= kFileNumberMask);
  71. return number | (path_id * (kFileNumberMask + 1));
  72. }
  73. void FileMetaData::UpdateBoundaries(const Slice& key, const Slice& value,
  74. SequenceNumber seqno,
  75. ValueType value_type) {
  76. if (smallest.size() == 0) {
  77. smallest.DecodeFrom(key);
  78. }
  79. largest.DecodeFrom(key);
  80. fd.smallest_seqno = std::min(fd.smallest_seqno, seqno);
  81. fd.largest_seqno = std::max(fd.largest_seqno, seqno);
  82. #ifndef ROCKSDB_LITE
  83. if (value_type == kTypeBlobIndex) {
  84. BlobIndex blob_index;
  85. const Status s = blob_index.DecodeFrom(value);
  86. if (!s.ok()) {
  87. return;
  88. }
  89. if (blob_index.IsInlined()) {
  90. return;
  91. }
  92. if (blob_index.HasTTL()) {
  93. return;
  94. }
  95. // Paranoid check: this should not happen because BlobDB numbers the blob
  96. // files starting from 1.
  97. if (blob_index.file_number() == kInvalidBlobFileNumber) {
  98. return;
  99. }
  100. if (oldest_blob_file_number == kInvalidBlobFileNumber ||
  101. oldest_blob_file_number > blob_index.file_number()) {
  102. oldest_blob_file_number = blob_index.file_number();
  103. }
  104. }
  105. #else
  106. (void)value;
  107. (void)value_type;
  108. #endif
  109. }
  110. void VersionEdit::Clear() {
  111. max_level_ = 0;
  112. db_id_.clear();
  113. comparator_.clear();
  114. log_number_ = 0;
  115. prev_log_number_ = 0;
  116. next_file_number_ = 0;
  117. max_column_family_ = 0;
  118. min_log_number_to_keep_ = 0;
  119. last_sequence_ = 0;
  120. has_db_id_ = false;
  121. has_comparator_ = false;
  122. has_log_number_ = false;
  123. has_prev_log_number_ = false;
  124. has_next_file_number_ = false;
  125. has_max_column_family_ = false;
  126. has_min_log_number_to_keep_ = false;
  127. has_last_sequence_ = false;
  128. deleted_files_.clear();
  129. new_files_.clear();
  130. column_family_ = 0;
  131. is_column_family_add_ = false;
  132. is_column_family_drop_ = false;
  133. column_family_name_.clear();
  134. is_in_atomic_group_ = false;
  135. remaining_entries_ = 0;
  136. }
  137. bool VersionEdit::EncodeTo(std::string* dst) const {
  138. if (has_db_id_) {
  139. PutVarint32(dst, kDbId);
  140. PutLengthPrefixedSlice(dst, db_id_);
  141. }
  142. if (has_comparator_) {
  143. PutVarint32(dst, kComparator);
  144. PutLengthPrefixedSlice(dst, comparator_);
  145. }
  146. if (has_log_number_) {
  147. PutVarint32Varint64(dst, kLogNumber, log_number_);
  148. }
  149. if (has_prev_log_number_) {
  150. PutVarint32Varint64(dst, kPrevLogNumber, prev_log_number_);
  151. }
  152. if (has_next_file_number_) {
  153. PutVarint32Varint64(dst, kNextFileNumber, next_file_number_);
  154. }
  155. if (has_max_column_family_) {
  156. PutVarint32Varint32(dst, kMaxColumnFamily, max_column_family_);
  157. }
  158. if (has_last_sequence_) {
  159. PutVarint32Varint64(dst, kLastSequence, last_sequence_);
  160. }
  161. for (const auto& deleted : deleted_files_) {
  162. PutVarint32Varint32Varint64(dst, kDeletedFile, deleted.first /* level */,
  163. deleted.second /* file number */);
  164. }
  165. bool min_log_num_written = false;
  166. for (size_t i = 0; i < new_files_.size(); i++) {
  167. const FileMetaData& f = new_files_[i].second;
  168. if (!f.smallest.Valid() || !f.largest.Valid()) {
  169. return false;
  170. }
  171. PutVarint32(dst, kNewFile4);
  172. PutVarint32Varint64(dst, new_files_[i].first /* level */, f.fd.GetNumber());
  173. PutVarint64(dst, f.fd.GetFileSize());
  174. PutLengthPrefixedSlice(dst, f.smallest.Encode());
  175. PutLengthPrefixedSlice(dst, f.largest.Encode());
  176. PutVarint64Varint64(dst, f.fd.smallest_seqno, f.fd.largest_seqno);
  177. // Customized fields' format:
  178. // +-----------------------------+
  179. // | 1st field's tag (varint32) |
  180. // +-----------------------------+
  181. // | 1st field's size (varint32) |
  182. // +-----------------------------+
  183. // | bytes for 1st field |
  184. // | (based on size decoded) |
  185. // +-----------------------------+
  186. // | |
  187. // | ...... |
  188. // | |
  189. // +-----------------------------+
  190. // | last field's size (varint32)|
  191. // +-----------------------------+
  192. // | bytes for last field |
  193. // | (based on size decoded) |
  194. // +-----------------------------+
  195. // | terminating tag (varint32) |
  196. // +-----------------------------+
  197. //
  198. // Customized encoding for fields:
  199. // tag kPathId: 1 byte as path_id
  200. // tag kNeedCompaction:
  201. // now only can take one char value 1 indicating need-compaction
  202. //
  203. PutVarint32(dst, CustomTag::kOldestAncesterTime);
  204. std::string varint_oldest_ancester_time;
  205. PutVarint64(&varint_oldest_ancester_time, f.oldest_ancester_time);
  206. TEST_SYNC_POINT_CALLBACK("VersionEdit::EncodeTo:VarintOldestAncesterTime",
  207. &varint_oldest_ancester_time);
  208. PutLengthPrefixedSlice(dst, Slice(varint_oldest_ancester_time));
  209. PutVarint32(dst, CustomTag::kFileCreationTime);
  210. std::string varint_file_creation_time;
  211. PutVarint64(&varint_file_creation_time, f.file_creation_time);
  212. TEST_SYNC_POINT_CALLBACK("VersionEdit::EncodeTo:VarintFileCreationTime",
  213. &varint_file_creation_time);
  214. PutLengthPrefixedSlice(dst, Slice(varint_file_creation_time));
  215. PutVarint32(dst, CustomTag::kFileChecksum);
  216. PutLengthPrefixedSlice(dst, Slice(f.file_checksum));
  217. PutVarint32(dst, CustomTag::kFileChecksumFuncName);
  218. PutLengthPrefixedSlice(dst, Slice(f.file_checksum_func_name));
  219. if (f.fd.GetPathId() != 0) {
  220. PutVarint32(dst, CustomTag::kPathId);
  221. char p = static_cast<char>(f.fd.GetPathId());
  222. PutLengthPrefixedSlice(dst, Slice(&p, 1));
  223. }
  224. if (f.marked_for_compaction) {
  225. PutVarint32(dst, CustomTag::kNeedCompaction);
  226. char p = static_cast<char>(1);
  227. PutLengthPrefixedSlice(dst, Slice(&p, 1));
  228. }
  229. if (has_min_log_number_to_keep_ && !min_log_num_written) {
  230. PutVarint32(dst, CustomTag::kMinLogNumberToKeepHack);
  231. std::string varint_log_number;
  232. PutFixed64(&varint_log_number, min_log_number_to_keep_);
  233. PutLengthPrefixedSlice(dst, Slice(varint_log_number));
  234. min_log_num_written = true;
  235. }
  236. if (f.oldest_blob_file_number != kInvalidBlobFileNumber) {
  237. PutVarint32(dst, CustomTag::kOldestBlobFileNumber);
  238. std::string oldest_blob_file_number;
  239. PutVarint64(&oldest_blob_file_number, f.oldest_blob_file_number);
  240. PutLengthPrefixedSlice(dst, Slice(oldest_blob_file_number));
  241. }
  242. TEST_SYNC_POINT_CALLBACK("VersionEdit::EncodeTo:NewFile4:CustomizeFields",
  243. dst);
  244. PutVarint32(dst, CustomTag::kTerminate);
  245. }
  246. // 0 is default and does not need to be explicitly written
  247. if (column_family_ != 0) {
  248. PutVarint32Varint32(dst, kColumnFamily, column_family_);
  249. }
  250. if (is_column_family_add_) {
  251. PutVarint32(dst, kColumnFamilyAdd);
  252. PutLengthPrefixedSlice(dst, Slice(column_family_name_));
  253. }
  254. if (is_column_family_drop_) {
  255. PutVarint32(dst, kColumnFamilyDrop);
  256. }
  257. if (is_in_atomic_group_) {
  258. PutVarint32(dst, kInAtomicGroup);
  259. PutVarint32(dst, remaining_entries_);
  260. }
  261. return true;
  262. }
  263. static bool GetInternalKey(Slice* input, InternalKey* dst) {
  264. Slice str;
  265. if (GetLengthPrefixedSlice(input, &str)) {
  266. dst->DecodeFrom(str);
  267. return dst->Valid();
  268. } else {
  269. return false;
  270. }
  271. }
  272. bool VersionEdit::GetLevel(Slice* input, int* level, const char** /*msg*/) {
  273. uint32_t v = 0;
  274. if (GetVarint32(input, &v)) {
  275. *level = v;
  276. if (max_level_ < *level) {
  277. max_level_ = *level;
  278. }
  279. return true;
  280. } else {
  281. return false;
  282. }
  283. }
  284. const char* VersionEdit::DecodeNewFile4From(Slice* input) {
  285. const char* msg = nullptr;
  286. int level = 0;
  287. FileMetaData f;
  288. uint64_t number = 0;
  289. uint32_t path_id = 0;
  290. uint64_t file_size = 0;
  291. SequenceNumber smallest_seqno = 0;
  292. SequenceNumber largest_seqno = kMaxSequenceNumber;
  293. // Since this is the only forward-compatible part of the code, we hack new
  294. // extension into this record. When we do, we set this boolean to distinguish
  295. // the record from the normal NewFile records.
  296. if (GetLevel(input, &level, &msg) && GetVarint64(input, &number) &&
  297. GetVarint64(input, &file_size) && GetInternalKey(input, &f.smallest) &&
  298. GetInternalKey(input, &f.largest) &&
  299. GetVarint64(input, &smallest_seqno) &&
  300. GetVarint64(input, &largest_seqno)) {
  301. // See comments in VersionEdit::EncodeTo() for format of customized fields
  302. while (true) {
  303. uint32_t custom_tag = 0;
  304. Slice field;
  305. if (!GetVarint32(input, &custom_tag)) {
  306. return "new-file4 custom field";
  307. }
  308. if (custom_tag == kTerminate) {
  309. break;
  310. }
  311. if (!GetLengthPrefixedSlice(input, &field)) {
  312. return "new-file4 custom field length prefixed slice error";
  313. }
  314. switch (custom_tag) {
  315. case kPathId:
  316. if (field.size() != 1) {
  317. return "path_id field wrong size";
  318. }
  319. path_id = field[0];
  320. if (path_id > 3) {
  321. return "path_id wrong vaue";
  322. }
  323. break;
  324. case kOldestAncesterTime:
  325. if (!GetVarint64(&field, &f.oldest_ancester_time)) {
  326. return "invalid oldest ancester time";
  327. }
  328. break;
  329. case kFileCreationTime:
  330. if (!GetVarint64(&field, &f.file_creation_time)) {
  331. return "invalid file creation time";
  332. }
  333. break;
  334. case kFileChecksum:
  335. f.file_checksum = field.ToString();
  336. break;
  337. case kFileChecksumFuncName:
  338. f.file_checksum_func_name = field.ToString();
  339. break;
  340. case kNeedCompaction:
  341. if (field.size() != 1) {
  342. return "need_compaction field wrong size";
  343. }
  344. f.marked_for_compaction = (field[0] == 1);
  345. break;
  346. case kMinLogNumberToKeepHack:
  347. // This is a hack to encode kMinLogNumberToKeep in a
  348. // forward-compatible fashion.
  349. if (!GetFixed64(&field, &min_log_number_to_keep_)) {
  350. return "deleted log number malformatted";
  351. }
  352. has_min_log_number_to_keep_ = true;
  353. break;
  354. case kOldestBlobFileNumber:
  355. if (!GetVarint64(&field, &f.oldest_blob_file_number)) {
  356. return "invalid oldest blob file number";
  357. }
  358. break;
  359. default:
  360. if ((custom_tag & kCustomTagNonSafeIgnoreMask) != 0) {
  361. // Should not proceed if cannot understand it
  362. return "new-file4 custom field not supported";
  363. }
  364. break;
  365. }
  366. }
  367. } else {
  368. return "new-file4 entry";
  369. }
  370. f.fd =
  371. FileDescriptor(number, path_id, file_size, smallest_seqno, largest_seqno);
  372. new_files_.push_back(std::make_pair(level, f));
  373. return nullptr;
  374. }
  375. Status VersionEdit::DecodeFrom(const Slice& src) {
  376. Clear();
  377. Slice input = src;
  378. const char* msg = nullptr;
  379. uint32_t tag = 0;
  380. // Temporary storage for parsing
  381. int level = 0;
  382. FileMetaData f;
  383. Slice str;
  384. InternalKey key;
  385. while (msg == nullptr && GetVarint32(&input, &tag)) {
  386. switch (tag) {
  387. case kDbId:
  388. if (GetLengthPrefixedSlice(&input, &str)) {
  389. db_id_ = str.ToString();
  390. has_db_id_ = true;
  391. } else {
  392. msg = "db id";
  393. }
  394. break;
  395. case kComparator:
  396. if (GetLengthPrefixedSlice(&input, &str)) {
  397. comparator_ = str.ToString();
  398. has_comparator_ = true;
  399. } else {
  400. msg = "comparator name";
  401. }
  402. break;
  403. case kLogNumber:
  404. if (GetVarint64(&input, &log_number_)) {
  405. has_log_number_ = true;
  406. } else {
  407. msg = "log number";
  408. }
  409. break;
  410. case kPrevLogNumber:
  411. if (GetVarint64(&input, &prev_log_number_)) {
  412. has_prev_log_number_ = true;
  413. } else {
  414. msg = "previous log number";
  415. }
  416. break;
  417. case kNextFileNumber:
  418. if (GetVarint64(&input, &next_file_number_)) {
  419. has_next_file_number_ = true;
  420. } else {
  421. msg = "next file number";
  422. }
  423. break;
  424. case kMaxColumnFamily:
  425. if (GetVarint32(&input, &max_column_family_)) {
  426. has_max_column_family_ = true;
  427. } else {
  428. msg = "max column family";
  429. }
  430. break;
  431. case kMinLogNumberToKeep:
  432. if (GetVarint64(&input, &min_log_number_to_keep_)) {
  433. has_min_log_number_to_keep_ = true;
  434. } else {
  435. msg = "min log number to kee";
  436. }
  437. break;
  438. case kLastSequence:
  439. if (GetVarint64(&input, &last_sequence_)) {
  440. has_last_sequence_ = true;
  441. } else {
  442. msg = "last sequence number";
  443. }
  444. break;
  445. case kCompactPointer:
  446. if (GetLevel(&input, &level, &msg) &&
  447. GetInternalKey(&input, &key)) {
  448. // we don't use compact pointers anymore,
  449. // but we should not fail if they are still
  450. // in manifest
  451. } else {
  452. if (!msg) {
  453. msg = "compaction pointer";
  454. }
  455. }
  456. break;
  457. case kDeletedFile: {
  458. uint64_t number = 0;
  459. if (GetLevel(&input, &level, &msg) && GetVarint64(&input, &number)) {
  460. deleted_files_.insert(std::make_pair(level, number));
  461. } else {
  462. if (!msg) {
  463. msg = "deleted file";
  464. }
  465. }
  466. break;
  467. }
  468. case kNewFile: {
  469. uint64_t number = 0;
  470. uint64_t file_size = 0;
  471. if (GetLevel(&input, &level, &msg) && GetVarint64(&input, &number) &&
  472. GetVarint64(&input, &file_size) &&
  473. GetInternalKey(&input, &f.smallest) &&
  474. GetInternalKey(&input, &f.largest)) {
  475. f.fd = FileDescriptor(number, 0, file_size);
  476. new_files_.push_back(std::make_pair(level, f));
  477. } else {
  478. if (!msg) {
  479. msg = "new-file entry";
  480. }
  481. }
  482. break;
  483. }
  484. case kNewFile2: {
  485. uint64_t number = 0;
  486. uint64_t file_size = 0;
  487. SequenceNumber smallest_seqno = 0;
  488. SequenceNumber largest_seqno = kMaxSequenceNumber;
  489. if (GetLevel(&input, &level, &msg) && GetVarint64(&input, &number) &&
  490. GetVarint64(&input, &file_size) &&
  491. GetInternalKey(&input, &f.smallest) &&
  492. GetInternalKey(&input, &f.largest) &&
  493. GetVarint64(&input, &smallest_seqno) &&
  494. GetVarint64(&input, &largest_seqno)) {
  495. f.fd = FileDescriptor(number, 0, file_size, smallest_seqno,
  496. largest_seqno);
  497. new_files_.push_back(std::make_pair(level, f));
  498. } else {
  499. if (!msg) {
  500. msg = "new-file2 entry";
  501. }
  502. }
  503. break;
  504. }
  505. case kNewFile3: {
  506. uint64_t number = 0;
  507. uint32_t path_id = 0;
  508. uint64_t file_size = 0;
  509. SequenceNumber smallest_seqno = 0;
  510. SequenceNumber largest_seqno = kMaxSequenceNumber;
  511. if (GetLevel(&input, &level, &msg) && GetVarint64(&input, &number) &&
  512. GetVarint32(&input, &path_id) && GetVarint64(&input, &file_size) &&
  513. GetInternalKey(&input, &f.smallest) &&
  514. GetInternalKey(&input, &f.largest) &&
  515. GetVarint64(&input, &smallest_seqno) &&
  516. GetVarint64(&input, &largest_seqno)) {
  517. f.fd = FileDescriptor(number, path_id, file_size, smallest_seqno,
  518. largest_seqno);
  519. new_files_.push_back(std::make_pair(level, f));
  520. } else {
  521. if (!msg) {
  522. msg = "new-file3 entry";
  523. }
  524. }
  525. break;
  526. }
  527. case kNewFile4: {
  528. msg = DecodeNewFile4From(&input);
  529. break;
  530. }
  531. case kColumnFamily:
  532. if (!GetVarint32(&input, &column_family_)) {
  533. if (!msg) {
  534. msg = "set column family id";
  535. }
  536. }
  537. break;
  538. case kColumnFamilyAdd:
  539. if (GetLengthPrefixedSlice(&input, &str)) {
  540. is_column_family_add_ = true;
  541. column_family_name_ = str.ToString();
  542. } else {
  543. if (!msg) {
  544. msg = "column family add";
  545. }
  546. }
  547. break;
  548. case kColumnFamilyDrop:
  549. is_column_family_drop_ = true;
  550. break;
  551. case kInAtomicGroup:
  552. is_in_atomic_group_ = true;
  553. if (!GetVarint32(&input, &remaining_entries_)) {
  554. if (!msg) {
  555. msg = "remaining entries";
  556. }
  557. }
  558. break;
  559. default:
  560. if (tag & kTagSafeIgnoreMask) {
  561. // Tag from future which can be safely ignored.
  562. // The next field must be the length of the entry.
  563. uint32_t field_len;
  564. if (!GetVarint32(&input, &field_len) ||
  565. static_cast<size_t>(field_len) > input.size()) {
  566. if (!msg) {
  567. msg = "safely ignoreable tag length error";
  568. }
  569. } else {
  570. input.remove_prefix(static_cast<size_t>(field_len));
  571. }
  572. } else {
  573. msg = "unknown tag";
  574. }
  575. break;
  576. }
  577. }
  578. if (msg == nullptr && !input.empty()) {
  579. msg = "invalid tag";
  580. }
  581. Status result;
  582. if (msg != nullptr) {
  583. result = Status::Corruption("VersionEdit", msg);
  584. }
  585. return result;
  586. }
  587. std::string VersionEdit::DebugString(bool hex_key) const {
  588. std::string r;
  589. r.append("VersionEdit {");
  590. if (has_db_id_) {
  591. r.append("\n DB ID: ");
  592. r.append(db_id_);
  593. }
  594. if (has_comparator_) {
  595. r.append("\n Comparator: ");
  596. r.append(comparator_);
  597. }
  598. if (has_log_number_) {
  599. r.append("\n LogNumber: ");
  600. AppendNumberTo(&r, log_number_);
  601. }
  602. if (has_prev_log_number_) {
  603. r.append("\n PrevLogNumber: ");
  604. AppendNumberTo(&r, prev_log_number_);
  605. }
  606. if (has_next_file_number_) {
  607. r.append("\n NextFileNumber: ");
  608. AppendNumberTo(&r, next_file_number_);
  609. }
  610. if (has_max_column_family_) {
  611. r.append("\n MaxColumnFamily: ");
  612. AppendNumberTo(&r, max_column_family_);
  613. }
  614. if (has_min_log_number_to_keep_) {
  615. r.append("\n MinLogNumberToKeep: ");
  616. AppendNumberTo(&r, min_log_number_to_keep_);
  617. }
  618. if (has_last_sequence_) {
  619. r.append("\n LastSeq: ");
  620. AppendNumberTo(&r, last_sequence_);
  621. }
  622. for (const auto& deleted_file : deleted_files_) {
  623. r.append("\n DeleteFile: ");
  624. AppendNumberTo(&r, deleted_file.first);
  625. r.append(" ");
  626. AppendNumberTo(&r, deleted_file.second);
  627. }
  628. for (size_t i = 0; i < new_files_.size(); i++) {
  629. const FileMetaData& f = new_files_[i].second;
  630. r.append("\n AddFile: ");
  631. AppendNumberTo(&r, new_files_[i].first);
  632. r.append(" ");
  633. AppendNumberTo(&r, f.fd.GetNumber());
  634. r.append(" ");
  635. AppendNumberTo(&r, f.fd.GetFileSize());
  636. r.append(" ");
  637. r.append(f.smallest.DebugString(hex_key));
  638. r.append(" .. ");
  639. r.append(f.largest.DebugString(hex_key));
  640. if (f.oldest_blob_file_number != kInvalidBlobFileNumber) {
  641. r.append(" blob_file:");
  642. AppendNumberTo(&r, f.oldest_blob_file_number);
  643. }
  644. r.append(" oldest_ancester_time:");
  645. AppendNumberTo(&r, f.oldest_ancester_time);
  646. r.append(" file_creation_time:");
  647. AppendNumberTo(&r, f.file_creation_time);
  648. r.append(" file_checksum:");
  649. r.append(f.file_checksum);
  650. r.append(" file_checksum_func_name: ");
  651. r.append(f.file_checksum_func_name);
  652. }
  653. r.append("\n ColumnFamily: ");
  654. AppendNumberTo(&r, column_family_);
  655. if (is_column_family_add_) {
  656. r.append("\n ColumnFamilyAdd: ");
  657. r.append(column_family_name_);
  658. }
  659. if (is_column_family_drop_) {
  660. r.append("\n ColumnFamilyDrop");
  661. }
  662. if (is_in_atomic_group_) {
  663. r.append("\n AtomicGroup: ");
  664. AppendNumberTo(&r, remaining_entries_);
  665. r.append(" entries remains");
  666. }
  667. r.append("\n}\n");
  668. return r;
  669. }
  670. std::string VersionEdit::DebugJSON(int edit_num, bool hex_key) const {
  671. JSONWriter jw;
  672. jw << "EditNumber" << edit_num;
  673. if (has_db_id_) {
  674. jw << "DB ID" << db_id_;
  675. }
  676. if (has_comparator_) {
  677. jw << "Comparator" << comparator_;
  678. }
  679. if (has_log_number_) {
  680. jw << "LogNumber" << log_number_;
  681. }
  682. if (has_prev_log_number_) {
  683. jw << "PrevLogNumber" << prev_log_number_;
  684. }
  685. if (has_next_file_number_) {
  686. jw << "NextFileNumber" << next_file_number_;
  687. }
  688. if (has_max_column_family_) {
  689. jw << "MaxColumnFamily" << max_column_family_;
  690. }
  691. if (has_min_log_number_to_keep_) {
  692. jw << "MinLogNumberToKeep" << min_log_number_to_keep_;
  693. }
  694. if (has_last_sequence_) {
  695. jw << "LastSeq" << last_sequence_;
  696. }
  697. if (!deleted_files_.empty()) {
  698. jw << "DeletedFiles";
  699. jw.StartArray();
  700. for (const auto& deleted_file : deleted_files_) {
  701. jw.StartArrayedObject();
  702. jw << "Level" << deleted_file.first;
  703. jw << "FileNumber" << deleted_file.second;
  704. jw.EndArrayedObject();
  705. }
  706. jw.EndArray();
  707. }
  708. if (!new_files_.empty()) {
  709. jw << "AddedFiles";
  710. jw.StartArray();
  711. for (size_t i = 0; i < new_files_.size(); i++) {
  712. jw.StartArrayedObject();
  713. jw << "Level" << new_files_[i].first;
  714. const FileMetaData& f = new_files_[i].second;
  715. jw << "FileNumber" << f.fd.GetNumber();
  716. jw << "FileSize" << f.fd.GetFileSize();
  717. jw << "SmallestIKey" << f.smallest.DebugString(hex_key);
  718. jw << "LargestIKey" << f.largest.DebugString(hex_key);
  719. if (f.oldest_blob_file_number != kInvalidBlobFileNumber) {
  720. jw << "OldestBlobFile" << f.oldest_blob_file_number;
  721. }
  722. jw.EndArrayedObject();
  723. }
  724. jw.EndArray();
  725. }
  726. jw << "ColumnFamily" << column_family_;
  727. if (is_column_family_add_) {
  728. jw << "ColumnFamilyAdd" << column_family_name_;
  729. }
  730. if (is_column_family_drop_) {
  731. jw << "ColumnFamilyDrop" << column_family_name_;
  732. }
  733. if (is_in_atomic_group_) {
  734. jw << "AtomicGroup" << remaining_entries_;
  735. }
  736. jw.EndObject();
  737. return jw.Get();
  738. }
  739. } // namespace ROCKSDB_NAMESPACE