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 10 #pragma once 11 #include <algorithm> 12 #include <set> 13 #include <string> 14 #include <utility> 15 #include <vector> 16 17 #include "db/blob/blob_file_addition.h" 18 #include "db/blob/blob_file_garbage.h" 19 #include "db/dbformat.h" 20 #include "db/wal_edit.h" 21 #include "memory/arena.h" 22 #include "rocksdb/cache.h" 23 #include "table/table_reader.h" 24 #include "util/autovector.h" 25 26 namespace ROCKSDB_NAMESPACE { 27 28 // Tag numbers for serialized VersionEdit. These numbers are written to 29 // disk and should not be changed. The number should be forward compatible so 30 // users can down-grade RocksDB safely. A future Tag is ignored by doing '&' 31 // between Tag and kTagSafeIgnoreMask field. 32 enum Tag : uint32_t { 33 kComparator = 1, 34 kLogNumber = 2, 35 kNextFileNumber = 3, 36 kLastSequence = 4, 37 kCompactPointer = 5, 38 kDeletedFile = 6, 39 kNewFile = 7, 40 // 8 was used for large value refs 41 kPrevLogNumber = 9, 42 kMinLogNumberToKeep = 10, 43 44 // these are new formats divergent from open source leveldb 45 kNewFile2 = 100, 46 kNewFile3 = 102, 47 kNewFile4 = 103, // 4th (the latest) format version of adding files 48 kColumnFamily = 200, // specify column family for version edit 49 kColumnFamilyAdd = 201, 50 kColumnFamilyDrop = 202, 51 kMaxColumnFamily = 203, 52 53 kInAtomicGroup = 300, 54 55 kBlobFileAddition = 400, 56 kBlobFileGarbage, 57 58 // Mask for an unidentified tag from the future which can be safely ignored. 59 kTagSafeIgnoreMask = 1 << 13, 60 61 // Forward compatible (aka ignorable) records 62 kDbId, 63 kBlobFileAddition_DEPRECATED, 64 kBlobFileGarbage_DEPRECATED, 65 kWalAddition, 66 kWalDeletion, 67 kFullHistoryTsLow, 68 kWalAddition2, 69 kWalDeletion2, 70 }; 71 72 enum NewFileCustomTag : uint32_t { 73 kTerminate = 1, // The end of customized fields 74 kNeedCompaction = 2, 75 // Since Manifest is not entirely forward-compatible, we currently encode 76 // kMinLogNumberToKeep as part of NewFile as a hack. This should be removed 77 // when manifest becomes forward-compatible. 78 kMinLogNumberToKeepHack = 3, 79 kOldestBlobFileNumber = 4, 80 kOldestAncesterTime = 5, 81 kFileCreationTime = 6, 82 kFileChecksum = 7, 83 kFileChecksumFuncName = 8, 84 kTemperature = 9, 85 86 // If this bit for the custom tag is set, opening DB should fail if 87 // we don't know this field. 88 kCustomTagNonSafeIgnoreMask = 1 << 6, 89 90 // Forward incompatible (aka unignorable) fields 91 kPathId, 92 }; 93 94 class VersionSet; 95 96 constexpr uint64_t kFileNumberMask = 0x3FFFFFFFFFFFFFFF; 97 constexpr uint64_t kUnknownOldestAncesterTime = 0; 98 constexpr uint64_t kUnknownFileCreationTime = 0; 99 100 extern uint64_t PackFileNumberAndPathId(uint64_t number, uint64_t path_id); 101 102 // A copyable structure contains information needed to read data from an SST 103 // file. It can contain a pointer to a table reader opened for the file, or 104 // file number and size, which can be used to create a new table reader for it. 105 // The behavior is undefined when a copied of the structure is used when the 106 // file is not in any live version any more. 107 struct FileDescriptor { 108 // Table reader in table_reader_handle 109 TableReader* table_reader; 110 uint64_t packed_number_and_path_id; 111 uint64_t file_size; // File size in bytes 112 SequenceNumber smallest_seqno; // The smallest seqno in this file 113 SequenceNumber largest_seqno; // The largest seqno in this file 114 FileDescriptorFileDescriptor115 FileDescriptor() : FileDescriptor(0, 0, 0) {} 116 FileDescriptorFileDescriptor117 FileDescriptor(uint64_t number, uint32_t path_id, uint64_t _file_size) 118 : FileDescriptor(number, path_id, _file_size, kMaxSequenceNumber, 0) {} 119 FileDescriptorFileDescriptor120 FileDescriptor(uint64_t number, uint32_t path_id, uint64_t _file_size, 121 SequenceNumber _smallest_seqno, SequenceNumber _largest_seqno) 122 : table_reader(nullptr), 123 packed_number_and_path_id(PackFileNumberAndPathId(number, path_id)), 124 file_size(_file_size), 125 smallest_seqno(_smallest_seqno), 126 largest_seqno(_largest_seqno) {} 127 FileDescriptorFileDescriptor128 FileDescriptor(const FileDescriptor& fd) { *this = fd; } 129 130 FileDescriptor& operator=(const FileDescriptor& fd) { 131 table_reader = fd.table_reader; 132 packed_number_and_path_id = fd.packed_number_and_path_id; 133 file_size = fd.file_size; 134 smallest_seqno = fd.smallest_seqno; 135 largest_seqno = fd.largest_seqno; 136 return *this; 137 } 138 GetNumberFileDescriptor139 uint64_t GetNumber() const { 140 return packed_number_and_path_id & kFileNumberMask; 141 } GetPathIdFileDescriptor142 uint32_t GetPathId() const { 143 return static_cast<uint32_t>( 144 packed_number_and_path_id / (kFileNumberMask + 1)); 145 } GetFileSizeFileDescriptor146 uint64_t GetFileSize() const { return file_size; } 147 }; 148 149 struct FileSampledStats { FileSampledStatsFileSampledStats150 FileSampledStats() : num_reads_sampled(0) {} FileSampledStatsFileSampledStats151 FileSampledStats(const FileSampledStats& other) { *this = other; } 152 FileSampledStats& operator=(const FileSampledStats& other) { 153 num_reads_sampled = other.num_reads_sampled.load(); 154 return *this; 155 } 156 157 // number of user reads to this file. 158 mutable std::atomic<uint64_t> num_reads_sampled; 159 }; 160 161 struct FileMetaData { 162 FileDescriptor fd; 163 InternalKey smallest; // Smallest internal key served by table 164 InternalKey largest; // Largest internal key served by table 165 166 // Needs to be disposed when refs becomes 0. 167 Cache::Handle* table_reader_handle = nullptr; 168 169 FileSampledStats stats; 170 171 // Stats for compensating deletion entries during compaction 172 173 // File size compensated by deletion entry. 174 // This is updated in Version::UpdateAccumulatedStats() first time when the 175 // file is created or loaded. After it is updated (!= 0), it is immutable. 176 uint64_t compensated_file_size = 0; 177 // These values can mutate, but they can only be read or written from 178 // single-threaded LogAndApply thread 179 uint64_t num_entries = 0; // the number of entries. 180 uint64_t num_deletions = 0; // the number of deletion entries. 181 uint64_t raw_key_size = 0; // total uncompressed key size. 182 uint64_t raw_value_size = 0; // total uncompressed value size. 183 184 int refs = 0; // Reference count 185 186 bool being_compacted = false; // Is this file undergoing compaction? 187 bool init_stats_from_file = false; // true if the data-entry stats of this 188 // file has initialized from file. 189 190 bool marked_for_compaction = false; // True if client asked us nicely to 191 // compact this file. 192 Temperature temperature = Temperature::kUnknown; 193 194 // Used only in BlobDB. The file number of the oldest blob file this SST file 195 // refers to. 0 is an invalid value; BlobDB numbers the files starting from 1. 196 uint64_t oldest_blob_file_number = kInvalidBlobFileNumber; 197 198 // The file could be the compaction output from other SST files, which could 199 // in turn be outputs for compact older SST files. We track the memtable 200 // flush timestamp for the oldest SST file that eventually contribute data 201 // to this file. 0 means the information is not available. 202 uint64_t oldest_ancester_time = kUnknownOldestAncesterTime; 203 204 // Unix time when the SST file is created. 205 uint64_t file_creation_time = kUnknownFileCreationTime; 206 207 // File checksum 208 std::string file_checksum = kUnknownFileChecksum; 209 210 // File checksum function name 211 std::string file_checksum_func_name = kUnknownFileChecksumFuncName; 212 213 FileMetaData() = default; 214 FileMetaDataFileMetaData215 FileMetaData(uint64_t file, uint32_t file_path_id, uint64_t file_size, 216 const InternalKey& smallest_key, const InternalKey& largest_key, 217 const SequenceNumber& smallest_seq, 218 const SequenceNumber& largest_seq, bool marked_for_compact, 219 uint64_t oldest_blob_file, uint64_t _oldest_ancester_time, 220 uint64_t _file_creation_time, const std::string& _file_checksum, 221 const std::string& _file_checksum_func_name) 222 : fd(file, file_path_id, file_size, smallest_seq, largest_seq), 223 smallest(smallest_key), 224 largest(largest_key), 225 marked_for_compaction(marked_for_compact), 226 oldest_blob_file_number(oldest_blob_file), 227 oldest_ancester_time(_oldest_ancester_time), 228 file_creation_time(_file_creation_time), 229 file_checksum(_file_checksum), 230 file_checksum_func_name(_file_checksum_func_name) { 231 TEST_SYNC_POINT_CALLBACK("FileMetaData::FileMetaData", this); 232 } 233 234 // REQUIRED: Keys must be given to the function in sorted order (it expects 235 // the last key to be the largest). 236 void UpdateBoundaries(const Slice& key, const Slice& value, 237 SequenceNumber seqno, ValueType value_type); 238 239 // Unlike UpdateBoundaries, ranges do not need to be presented in any 240 // particular order. UpdateBoundariesForRangeFileMetaData241 void UpdateBoundariesForRange(const InternalKey& start, 242 const InternalKey& end, SequenceNumber seqno, 243 const InternalKeyComparator& icmp) { 244 if (smallest.size() == 0 || icmp.Compare(start, smallest) < 0) { 245 smallest = start; 246 } 247 if (largest.size() == 0 || icmp.Compare(largest, end) < 0) { 248 largest = end; 249 } 250 fd.smallest_seqno = std::min(fd.smallest_seqno, seqno); 251 fd.largest_seqno = std::max(fd.largest_seqno, seqno); 252 } 253 254 // Try to get oldest ancester time from the class itself or table properties 255 // if table reader is already pinned. 256 // 0 means the information is not available. TryGetOldestAncesterTimeFileMetaData257 uint64_t TryGetOldestAncesterTime() { 258 if (oldest_ancester_time != kUnknownOldestAncesterTime) { 259 return oldest_ancester_time; 260 } else if (fd.table_reader != nullptr && 261 fd.table_reader->GetTableProperties() != nullptr) { 262 return fd.table_reader->GetTableProperties()->creation_time; 263 } 264 return kUnknownOldestAncesterTime; 265 } 266 TryGetFileCreationTimeFileMetaData267 uint64_t TryGetFileCreationTime() { 268 if (file_creation_time != kUnknownFileCreationTime) { 269 return file_creation_time; 270 } else if (fd.table_reader != nullptr && 271 fd.table_reader->GetTableProperties() != nullptr) { 272 return fd.table_reader->GetTableProperties()->file_creation_time; 273 } 274 return kUnknownFileCreationTime; 275 } 276 }; 277 278 // A compressed copy of file meta data that just contain minimum data needed 279 // to server read operations, while still keeping the pointer to full metadata 280 // of the file in case it is needed. 281 struct FdWithKeyRange { 282 FileDescriptor fd; 283 FileMetaData* file_metadata; // Point to all metadata 284 Slice smallest_key; // slice that contain smallest key 285 Slice largest_key; // slice that contain largest key 286 FdWithKeyRangeFdWithKeyRange287 FdWithKeyRange() 288 : fd(), 289 file_metadata(nullptr), 290 smallest_key(), 291 largest_key() { 292 } 293 FdWithKeyRangeFdWithKeyRange294 FdWithKeyRange(FileDescriptor _fd, Slice _smallest_key, Slice _largest_key, 295 FileMetaData* _file_metadata) 296 : fd(_fd), 297 file_metadata(_file_metadata), 298 smallest_key(_smallest_key), 299 largest_key(_largest_key) {} 300 }; 301 302 // Data structure to store an array of FdWithKeyRange in one level 303 // Actual data is guaranteed to be stored closely 304 struct LevelFilesBrief { 305 size_t num_files; 306 FdWithKeyRange* files; LevelFilesBriefLevelFilesBrief307 LevelFilesBrief() { 308 num_files = 0; 309 files = nullptr; 310 } 311 }; 312 313 // The state of a DB at any given time is referred to as a Version. 314 // Any modification to the Version is considered a Version Edit. A Version is 315 // constructed by joining a sequence of Version Edits. Version Edits are written 316 // to the MANIFEST file. 317 class VersionEdit { 318 public: 319 void Clear(); 320 SetDBId(const std::string & db_id)321 void SetDBId(const std::string& db_id) { 322 has_db_id_ = true; 323 db_id_ = db_id; 324 } HasDbId()325 bool HasDbId() const { return has_db_id_; } GetDbId()326 const std::string& GetDbId() const { return db_id_; } 327 SetComparatorName(const Slice & name)328 void SetComparatorName(const Slice& name) { 329 has_comparator_ = true; 330 comparator_ = name.ToString(); 331 } HasComparatorName()332 bool HasComparatorName() const { return has_comparator_; } GetComparatorName()333 const std::string& GetComparatorName() const { return comparator_; } 334 SetLogNumber(uint64_t num)335 void SetLogNumber(uint64_t num) { 336 has_log_number_ = true; 337 log_number_ = num; 338 } HasLogNumber()339 bool HasLogNumber() const { return has_log_number_; } GetLogNumber()340 uint64_t GetLogNumber() const { return log_number_; } 341 SetPrevLogNumber(uint64_t num)342 void SetPrevLogNumber(uint64_t num) { 343 has_prev_log_number_ = true; 344 prev_log_number_ = num; 345 } HasPrevLogNumber()346 bool HasPrevLogNumber() const { return has_prev_log_number_; } GetPrevLogNumber()347 uint64_t GetPrevLogNumber() const { return prev_log_number_; } 348 SetNextFile(uint64_t num)349 void SetNextFile(uint64_t num) { 350 has_next_file_number_ = true; 351 next_file_number_ = num; 352 } HasNextFile()353 bool HasNextFile() const { return has_next_file_number_; } GetNextFile()354 uint64_t GetNextFile() const { return next_file_number_; } 355 SetMaxColumnFamily(uint32_t max_column_family)356 void SetMaxColumnFamily(uint32_t max_column_family) { 357 has_max_column_family_ = true; 358 max_column_family_ = max_column_family; 359 } HasMaxColumnFamily()360 bool HasMaxColumnFamily() const { return has_max_column_family_; } GetMaxColumnFamily()361 uint32_t GetMaxColumnFamily() const { return max_column_family_; } 362 SetMinLogNumberToKeep(uint64_t num)363 void SetMinLogNumberToKeep(uint64_t num) { 364 has_min_log_number_to_keep_ = true; 365 min_log_number_to_keep_ = num; 366 } HasMinLogNumberToKeep()367 bool HasMinLogNumberToKeep() const { return has_min_log_number_to_keep_; } GetMinLogNumberToKeep()368 uint64_t GetMinLogNumberToKeep() const { return min_log_number_to_keep_; } 369 SetLastSequence(SequenceNumber seq)370 void SetLastSequence(SequenceNumber seq) { 371 has_last_sequence_ = true; 372 last_sequence_ = seq; 373 } HasLastSequence()374 bool HasLastSequence() const { return has_last_sequence_; } GetLastSequence()375 SequenceNumber GetLastSequence() const { return last_sequence_; } 376 377 // Delete the specified table file from the specified level. DeleteFile(int level,uint64_t file)378 void DeleteFile(int level, uint64_t file) { 379 deleted_files_.emplace(level, file); 380 } 381 382 // Retrieve the table files deleted as well as their associated levels. 383 using DeletedFiles = std::set<std::pair<int, uint64_t>>; GetDeletedFiles()384 const DeletedFiles& GetDeletedFiles() const { return deleted_files_; } 385 386 // Add the specified table file at the specified level. 387 // REQUIRES: This version has not been saved (see VersionSet::SaveTo) 388 // REQUIRES: "smallest" and "largest" are smallest and largest keys in file 389 // REQUIRES: "oldest_blob_file_number" is the number of the oldest blob file 390 // referred to by this file if any, kInvalidBlobFileNumber otherwise. AddFile(int level,uint64_t file,uint32_t file_path_id,uint64_t file_size,const InternalKey & smallest,const InternalKey & largest,const SequenceNumber & smallest_seqno,const SequenceNumber & largest_seqno,bool marked_for_compaction,uint64_t oldest_blob_file_number,uint64_t oldest_ancester_time,uint64_t file_creation_time,const std::string & file_checksum,const std::string & file_checksum_func_name)391 void AddFile(int level, uint64_t file, uint32_t file_path_id, 392 uint64_t file_size, const InternalKey& smallest, 393 const InternalKey& largest, const SequenceNumber& smallest_seqno, 394 const SequenceNumber& largest_seqno, bool marked_for_compaction, 395 uint64_t oldest_blob_file_number, uint64_t oldest_ancester_time, 396 uint64_t file_creation_time, const std::string& file_checksum, 397 const std::string& file_checksum_func_name) { 398 assert(smallest_seqno <= largest_seqno); 399 new_files_.emplace_back( 400 level, FileMetaData(file, file_path_id, file_size, smallest, largest, 401 smallest_seqno, largest_seqno, 402 marked_for_compaction, oldest_blob_file_number, 403 oldest_ancester_time, file_creation_time, 404 file_checksum, file_checksum_func_name)); 405 } 406 AddFile(int level,const FileMetaData & f)407 void AddFile(int level, const FileMetaData& f) { 408 assert(f.fd.smallest_seqno <= f.fd.largest_seqno); 409 new_files_.emplace_back(level, f); 410 } 411 412 // Retrieve the table files added as well as their associated levels. 413 using NewFiles = std::vector<std::pair<int, FileMetaData>>; GetNewFiles()414 const NewFiles& GetNewFiles() const { return new_files_; } 415 416 // Add a new blob file. AddBlobFile(uint64_t blob_file_number,uint64_t total_blob_count,uint64_t total_blob_bytes,std::string checksum_method,std::string checksum_value)417 void AddBlobFile(uint64_t blob_file_number, uint64_t total_blob_count, 418 uint64_t total_blob_bytes, std::string checksum_method, 419 std::string checksum_value) { 420 blob_file_additions_.emplace_back( 421 blob_file_number, total_blob_count, total_blob_bytes, 422 std::move(checksum_method), std::move(checksum_value)); 423 } 424 AddBlobFile(BlobFileAddition blob_file_addition)425 void AddBlobFile(BlobFileAddition blob_file_addition) { 426 blob_file_additions_.emplace_back(std::move(blob_file_addition)); 427 } 428 429 // Retrieve all the blob files added. 430 using BlobFileAdditions = std::vector<BlobFileAddition>; GetBlobFileAdditions()431 const BlobFileAdditions& GetBlobFileAdditions() const { 432 return blob_file_additions_; 433 } 434 SetBlobFileAdditions(BlobFileAdditions blob_file_additions)435 void SetBlobFileAdditions(BlobFileAdditions blob_file_additions) { 436 assert(blob_file_additions_.empty()); 437 blob_file_additions_ = std::move(blob_file_additions); 438 } 439 440 // Add garbage for an existing blob file. Note: intentionally broken English 441 // follows. AddBlobFileGarbage(uint64_t blob_file_number,uint64_t garbage_blob_count,uint64_t garbage_blob_bytes)442 void AddBlobFileGarbage(uint64_t blob_file_number, 443 uint64_t garbage_blob_count, 444 uint64_t garbage_blob_bytes) { 445 blob_file_garbages_.emplace_back(blob_file_number, garbage_blob_count, 446 garbage_blob_bytes); 447 } 448 AddBlobFileGarbage(BlobFileGarbage blob_file_garbage)449 void AddBlobFileGarbage(BlobFileGarbage blob_file_garbage) { 450 blob_file_garbages_.emplace_back(std::move(blob_file_garbage)); 451 } 452 453 // Retrieve all the blob file garbage added. 454 using BlobFileGarbages = std::vector<BlobFileGarbage>; GetBlobFileGarbages()455 const BlobFileGarbages& GetBlobFileGarbages() const { 456 return blob_file_garbages_; 457 } 458 SetBlobFileGarbages(BlobFileGarbages blob_file_garbages)459 void SetBlobFileGarbages(BlobFileGarbages blob_file_garbages) { 460 assert(blob_file_garbages_.empty()); 461 blob_file_garbages_ = std::move(blob_file_garbages); 462 } 463 464 // Add a WAL (either just created or closed). 465 // AddWal and DeleteWalsBefore cannot be called on the same VersionEdit. 466 void AddWal(WalNumber number, WalMetadata metadata = WalMetadata()) { 467 assert(NumEntries() == wal_additions_.size()); 468 wal_additions_.emplace_back(number, std::move(metadata)); 469 } 470 471 // Retrieve all the added WALs. GetWalAdditions()472 const WalAdditions& GetWalAdditions() const { return wal_additions_; } 473 IsWalAddition()474 bool IsWalAddition() const { return !wal_additions_.empty(); } 475 476 // Delete a WAL (either directly deleted or archived). 477 // AddWal and DeleteWalsBefore cannot be called on the same VersionEdit. DeleteWalsBefore(WalNumber number)478 void DeleteWalsBefore(WalNumber number) { 479 assert((NumEntries() == 1) == !wal_deletion_.IsEmpty()); 480 wal_deletion_ = WalDeletion(number); 481 } 482 GetWalDeletion()483 const WalDeletion& GetWalDeletion() const { return wal_deletion_; } 484 IsWalDeletion()485 bool IsWalDeletion() const { return !wal_deletion_.IsEmpty(); } 486 IsWalManipulation()487 bool IsWalManipulation() const { 488 size_t entries = NumEntries(); 489 return (entries > 0) && ((entries == wal_additions_.size()) || 490 (entries == !wal_deletion_.IsEmpty())); 491 } 492 493 // Number of edits NumEntries()494 size_t NumEntries() const { 495 return new_files_.size() + deleted_files_.size() + 496 blob_file_additions_.size() + blob_file_garbages_.size() + 497 wal_additions_.size() + !wal_deletion_.IsEmpty(); 498 } 499 SetColumnFamily(uint32_t column_family_id)500 void SetColumnFamily(uint32_t column_family_id) { 501 column_family_ = column_family_id; 502 } GetColumnFamily()503 uint32_t GetColumnFamily() const { return column_family_; } 504 505 // set column family ID by calling SetColumnFamily() AddColumnFamily(const std::string & name)506 void AddColumnFamily(const std::string& name) { 507 assert(!is_column_family_drop_); 508 assert(!is_column_family_add_); 509 assert(NumEntries() == 0); 510 is_column_family_add_ = true; 511 column_family_name_ = name; 512 } 513 514 // set column family ID by calling SetColumnFamily() DropColumnFamily()515 void DropColumnFamily() { 516 assert(!is_column_family_drop_); 517 assert(!is_column_family_add_); 518 assert(NumEntries() == 0); 519 is_column_family_drop_ = true; 520 } 521 IsColumnFamilyManipulation()522 bool IsColumnFamilyManipulation() const { 523 return is_column_family_add_ || is_column_family_drop_; 524 } 525 IsColumnFamilyAdd()526 bool IsColumnFamilyAdd() const { return is_column_family_add_; } 527 IsColumnFamilyDrop()528 bool IsColumnFamilyDrop() const { return is_column_family_drop_; } 529 MarkAtomicGroup(uint32_t remaining_entries)530 void MarkAtomicGroup(uint32_t remaining_entries) { 531 is_in_atomic_group_ = true; 532 remaining_entries_ = remaining_entries; 533 } IsInAtomicGroup()534 bool IsInAtomicGroup() const { return is_in_atomic_group_; } GetRemainingEntries()535 uint32_t GetRemainingEntries() const { return remaining_entries_; } 536 HasFullHistoryTsLow()537 bool HasFullHistoryTsLow() const { return !full_history_ts_low_.empty(); } GetFullHistoryTsLow()538 const std::string& GetFullHistoryTsLow() const { 539 assert(HasFullHistoryTsLow()); 540 return full_history_ts_low_; 541 } SetFullHistoryTsLow(std::string full_history_ts_low)542 void SetFullHistoryTsLow(std::string full_history_ts_low) { 543 assert(!full_history_ts_low.empty()); 544 full_history_ts_low_ = std::move(full_history_ts_low); 545 } 546 547 // return true on success. 548 bool EncodeTo(std::string* dst) const; 549 Status DecodeFrom(const Slice& src); 550 551 std::string DebugString(bool hex_key = false) const; 552 std::string DebugJSON(int edit_num, bool hex_key = false) const; 553 554 private: 555 friend class ReactiveVersionSet; 556 friend class VersionEditHandlerBase; 557 friend class ListColumnFamiliesHandler; 558 friend class VersionEditHandler; 559 friend class VersionEditHandlerPointInTime; 560 friend class DumpManifestHandler; 561 friend class VersionSet; 562 friend class Version; 563 friend class AtomicGroupReadBuffer; 564 565 bool GetLevel(Slice* input, int* level, const char** msg); 566 567 const char* DecodeNewFile4From(Slice* input); 568 569 int max_level_ = 0; 570 std::string db_id_; 571 std::string comparator_; 572 uint64_t log_number_ = 0; 573 uint64_t prev_log_number_ = 0; 574 uint64_t next_file_number_ = 0; 575 uint32_t max_column_family_ = 0; 576 // The most recent WAL log number that is deleted 577 uint64_t min_log_number_to_keep_ = 0; 578 SequenceNumber last_sequence_ = 0; 579 bool has_db_id_ = false; 580 bool has_comparator_ = false; 581 bool has_log_number_ = false; 582 bool has_prev_log_number_ = false; 583 bool has_next_file_number_ = false; 584 bool has_max_column_family_ = false; 585 bool has_min_log_number_to_keep_ = false; 586 bool has_last_sequence_ = false; 587 588 DeletedFiles deleted_files_; 589 NewFiles new_files_; 590 591 BlobFileAdditions blob_file_additions_; 592 BlobFileGarbages blob_file_garbages_; 593 594 WalAdditions wal_additions_; 595 WalDeletion wal_deletion_; 596 597 // Each version edit record should have column_family_ set 598 // If it's not set, it is default (0) 599 uint32_t column_family_ = 0; 600 // a version edit can be either column_family add or 601 // column_family drop. If it's column family add, 602 // it also includes column family name. 603 bool is_column_family_drop_ = false; 604 bool is_column_family_add_ = false; 605 std::string column_family_name_; 606 607 bool is_in_atomic_group_ = false; 608 uint32_t remaining_entries_ = 0; 609 610 std::string full_history_ts_low_; 611 }; 612 613 } // namespace ROCKSDB_NAMESPACE 614