git / moonbite-core / src/leveldb/db/version_edit.cc · raw

// 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,  // 8 was used for large value refs  kPrevLogNumber = 9};void VersionEdit::Clear() {  comparator_.clear();  log_number_ = 0;  prev_log_number_ = 0;  last_sequence_ = 0;  next_file_number_ = 0;  has_comparator_ = false;  has_log_number_ = false;  has_prev_log_number_ = false;  has_next_file_number_ = false;  has_last_sequence_ = false;  deleted_files_.clear();  new_files_.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_prev_log_number_) {    PutVarint32(dst, kPrevLogNumber);    PutVarint64(dst, prev_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 (size_t 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 (const auto& deleted_file_kvp : deleted_files_) {    PutVarint32(dst, kDeletedFile);    PutVarint32(dst, deleted_file_kvp.first);   // level    PutVarint64(dst, deleted_file_kvp.second);  // file number  }  for (size_t 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());  }}static bool GetInternalKey(Slice* input, InternalKey* dst) {  Slice str;  if (GetLengthPrefixedSlice(input, &str)) {    return dst->DecodeFrom(str);  } 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 = nullptr;  uint32_t tag;  // Temporary storage for parsing  int level;  uint64_t number;  FileMetaData f;  Slice str;  InternalKey key;  while (msg == nullptr && 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 kPrevLogNumber:        if (GetVarint64(&input, &prev_log_number_)) {          has_prev_log_number_ = true;        } else {          msg = "previous 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;      default:        msg = "unknown tag";        break;    }  }  if (msg == nullptr && !input.empty()) {    msg = "invalid tag";  }  Status result;  if (msg != nullptr) {    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_prev_log_number_) {    r.append("\n  PrevLogNumber: ");    AppendNumberTo(&r, prev_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 (size_t i = 0; i < compact_pointers_.size(); i++) {    r.append("\n  CompactPointer: ");    AppendNumberTo(&r, compact_pointers_[i].first);    r.append(" ");    r.append(compact_pointers_[i].second.DebugString());  }  for (const auto& deleted_files_kvp : deleted_files_) {    r.append("\n  DeleteFile: ");    AppendNumberTo(&r, deleted_files_kvp.first);    r.append(" ");    AppendNumberTo(&r, deleted_files_kvp.second);  }  for (size_t 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(" ");    r.append(f.smallest.DebugString());    r.append(" .. ");    r.append(f.largest.DebugString());  }  r.append("\n}\n");  return r;}}  // namespace leveldb