|
|
- // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file. See the AUTHORS file for names of contributors.
-
- #include "db/version_edit.h"
-
- #include "db/version_set.h"
- #include "util/coding.h"
-
- namespace leveldb {
-
- // Tag numbers for serialized VersionEdit. These numbers are written to
- // disk and should not be changed.
- enum Tag {
- kComparator = 1,
- kLogNumber = 2,
- kNextFileNumber = 3,
- kLastSequence = 4,
- kCompactPointer = 5,
- kDeletedFile = 6,
- kNewFile = 7,
- kLargeValueRef = 8,
- };
-
- void VersionEdit::Clear() {
- comparator_.clear();
- log_number_ = 0;
- last_sequence_ = 0;
- next_file_number_ = 0;
- has_comparator_ = false;
- has_log_number_ = false;
- has_next_file_number_ = false;
- has_last_sequence_ = false;
- deleted_files_.clear();
- new_files_.clear();
- large_refs_added_.clear();
- }
-
- void VersionEdit::EncodeTo(std::string* dst) const {
- if (has_comparator_) {
- PutVarint32(dst, kComparator);
- PutLengthPrefixedSlice(dst, comparator_);
- }
- if (has_log_number_) {
- PutVarint32(dst, kLogNumber);
- PutVarint64(dst, log_number_);
- }
- if (has_next_file_number_) {
- PutVarint32(dst, kNextFileNumber);
- PutVarint64(dst, next_file_number_);
- }
- if (has_last_sequence_) {
- PutVarint32(dst, kLastSequence);
- PutVarint64(dst, last_sequence_);
- }
-
- for (int i = 0; i < compact_pointers_.size(); i++) {
- PutVarint32(dst, kCompactPointer);
- PutVarint32(dst, compact_pointers_[i].first); // level
- PutLengthPrefixedSlice(dst, compact_pointers_[i].second.Encode());
- }
-
- for (DeletedFileSet::const_iterator iter = deleted_files_.begin();
- iter != deleted_files_.end();
- ++iter) {
- PutVarint32(dst, kDeletedFile);
- PutVarint32(dst, iter->first); // level
- PutVarint64(dst, iter->second); // file number
- }
-
- for (int i = 0; i < new_files_.size(); i++) {
- const FileMetaData& f = new_files_[i].second;
- PutVarint32(dst, kNewFile);
- PutVarint32(dst, new_files_[i].first); // level
- PutVarint64(dst, f.number);
- PutVarint64(dst, f.file_size);
- PutLengthPrefixedSlice(dst, f.smallest.Encode());
- PutLengthPrefixedSlice(dst, f.largest.Encode());
- }
-
- for (int i = 0; i < large_refs_added_.size(); i++) {
- const VersionEdit::Large& l = large_refs_added_[i];
- PutVarint32(dst, kLargeValueRef);
- PutLengthPrefixedSlice(dst,
- Slice(l.large_ref.data, LargeValueRef::ByteSize()));
- PutVarint64(dst, l.fnum);
- PutLengthPrefixedSlice(dst, l.internal_key.Encode());
- }
- }
-
- static bool GetInternalKey(Slice* input, InternalKey* dst) {
- Slice str;
- if (GetLengthPrefixedSlice(input, &str)) {
- dst->DecodeFrom(str);
- return true;
- } else {
- return false;
- }
- }
-
- static bool GetLevel(Slice* input, int* level) {
- uint32_t v;
- if (GetVarint32(input, &v) &&
- v < config::kNumLevels) {
- *level = v;
- return true;
- } else {
- return false;
- }
- }
-
- Status VersionEdit::DecodeFrom(const Slice& src) {
- Clear();
- Slice input = src;
- const char* msg = NULL;
- uint32_t tag;
-
- // Temporary storage for parsing
- int level;
- uint64_t number;
- FileMetaData f;
- Slice str;
- Large large;
- InternalKey key;
-
- while (msg == NULL && GetVarint32(&input, &tag)) {
- switch (tag) {
- case kComparator:
- if (GetLengthPrefixedSlice(&input, &str)) {
- comparator_ = str.ToString();
- has_comparator_ = true;
- } else {
- msg = "comparator name";
- }
- break;
-
- case kLogNumber:
- if (GetVarint64(&input, &log_number_)) {
- has_log_number_ = true;
- } else {
- msg = "log number";
- }
- break;
-
- case kNextFileNumber:
- if (GetVarint64(&input, &next_file_number_)) {
- has_next_file_number_ = true;
- } else {
- msg = "next file number";
- }
- break;
-
- case kLastSequence:
- if (GetVarint64(&input, &last_sequence_)) {
- has_last_sequence_ = true;
- } else {
- msg = "last sequence number";
- }
- break;
-
- case kCompactPointer:
- if (GetLevel(&input, &level) &&
- GetInternalKey(&input, &key)) {
- compact_pointers_.push_back(std::make_pair(level, key));
- } else {
- msg = "compaction pointer";
- }
- break;
-
- case kDeletedFile:
- if (GetLevel(&input, &level) &&
- GetVarint64(&input, &number)) {
- deleted_files_.insert(std::make_pair(level, number));
- } else {
- msg = "deleted file";
- }
- break;
-
- case kNewFile:
- if (GetLevel(&input, &level) &&
- GetVarint64(&input, &f.number) &&
- GetVarint64(&input, &f.file_size) &&
- GetInternalKey(&input, &f.smallest) &&
- GetInternalKey(&input, &f.largest)) {
- new_files_.push_back(std::make_pair(level, f));
- } else {
- msg = "new-file entry";
- }
- break;
-
- case kLargeValueRef:
- if (GetLengthPrefixedSlice(&input, &str) &&
- (str.size() == LargeValueRef::ByteSize()) &&
- GetVarint64(&input, &large.fnum) &&
- GetInternalKey(&input, &large.internal_key)) {
- large.large_ref = LargeValueRef::FromRef(str);
- large_refs_added_.push_back(large);
- } else {
- msg = "large ref";
- }
- break;
-
- default:
- msg = "unknown tag";
- break;
- }
- }
-
- if (msg == NULL && !input.empty()) {
- msg = "invalid tag";
- }
-
- Status result;
- if (msg != NULL) {
- result = Status::Corruption("VersionEdit", msg);
- }
- return result;
- }
-
- std::string VersionEdit::DebugString() const {
- std::string r;
- r.append("VersionEdit {");
- if (has_comparator_) {
- r.append("\n Comparator: ");
- r.append(comparator_);
- }
- if (has_log_number_) {
- r.append("\n LogNumber: ");
- AppendNumberTo(&r, log_number_);
- }
- if (has_next_file_number_) {
- r.append("\n NextFile: ");
- AppendNumberTo(&r, next_file_number_);
- }
- if (has_last_sequence_) {
- r.append("\n LastSeq: ");
- AppendNumberTo(&r, last_sequence_);
- }
- for (int i = 0; i < compact_pointers_.size(); i++) {
- r.append("\n CompactPointer: ");
- AppendNumberTo(&r, compact_pointers_[i].first);
- r.append(" '");
- AppendEscapedStringTo(&r, compact_pointers_[i].second.Encode());
- r.append("'");
- }
- for (DeletedFileSet::const_iterator iter = deleted_files_.begin();
- iter != deleted_files_.end();
- ++iter) {
- r.append("\n DeleteFile: ");
- AppendNumberTo(&r, iter->first);
- r.append(" ");
- AppendNumberTo(&r, iter->second);
- }
- for (int i = 0; i < new_files_.size(); i++) {
- const FileMetaData& f = new_files_[i].second;
- r.append("\n AddFile: ");
- AppendNumberTo(&r, new_files_[i].first);
- r.append(" ");
- AppendNumberTo(&r, f.number);
- r.append(" ");
- AppendNumberTo(&r, f.file_size);
- r.append(" '");
- AppendEscapedStringTo(&r, f.smallest.Encode());
- r.append("' .. '");
- AppendEscapedStringTo(&r, f.largest.Encode());
- r.append("'");
- }
- for (int i = 0; i < large_refs_added_.size(); i++) {
- const VersionEdit::Large& l = large_refs_added_[i];
- r.append("\n LargeRef: ");
- AppendNumberTo(&r, l.fnum);
- r.append(" ");
- r.append(LargeValueRefToFilenameString(l.large_ref));
- r.append(" '");
- AppendEscapedStringTo(&r, l.internal_key.Encode());
- r.append("'");
- }
- r.append("\n}\n");
- return r;
- }
-
- }
|