github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/database/leveldb.chai2010/src/version_edit.cc (about)

     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  
     5  #include "db/version_edit.h"
     6  
     7  #include "db/version_set.h"
     8  #include "util/coding.h"
     9  
    10  namespace leveldb {
    11  
    12  // Tag numbers for serialized VersionEdit.  These numbers are written to
    13  // disk and should not be changed.
    14  enum Tag {
    15    kComparator           = 1,
    16    kLogNumber            = 2,
    17    kNextFileNumber       = 3,
    18    kLastSequence         = 4,
    19    kCompactPointer       = 5,
    20    kDeletedFile          = 6,
    21    kNewFile              = 7,
    22    // 8 was used for large value refs
    23    kPrevLogNumber        = 9
    24  };
    25  
    26  void VersionEdit::Clear() {
    27    comparator_.clear();
    28    log_number_ = 0;
    29    prev_log_number_ = 0;
    30    last_sequence_ = 0;
    31    next_file_number_ = 0;
    32    has_comparator_ = false;
    33    has_log_number_ = false;
    34    has_prev_log_number_ = false;
    35    has_next_file_number_ = false;
    36    has_last_sequence_ = false;
    37    deleted_files_.clear();
    38    new_files_.clear();
    39  }
    40  
    41  void VersionEdit::EncodeTo(std::string* dst) const {
    42    if (has_comparator_) {
    43      PutVarint32(dst, kComparator);
    44      PutLengthPrefixedSlice(dst, comparator_);
    45    }
    46    if (has_log_number_) {
    47      PutVarint32(dst, kLogNumber);
    48      PutVarint64(dst, log_number_);
    49    }
    50    if (has_prev_log_number_) {
    51      PutVarint32(dst, kPrevLogNumber);
    52      PutVarint64(dst, prev_log_number_);
    53    }
    54    if (has_next_file_number_) {
    55      PutVarint32(dst, kNextFileNumber);
    56      PutVarint64(dst, next_file_number_);
    57    }
    58    if (has_last_sequence_) {
    59      PutVarint32(dst, kLastSequence);
    60      PutVarint64(dst, last_sequence_);
    61    }
    62  
    63    for (size_t i = 0; i < compact_pointers_.size(); i++) {
    64      PutVarint32(dst, kCompactPointer);
    65      PutVarint32(dst, compact_pointers_[i].first);  // level
    66      PutLengthPrefixedSlice(dst, compact_pointers_[i].second.Encode());
    67    }
    68  
    69    for (DeletedFileSet::const_iterator iter = deleted_files_.begin();
    70         iter != deleted_files_.end();
    71         ++iter) {
    72      PutVarint32(dst, kDeletedFile);
    73      PutVarint32(dst, iter->first);   // level
    74      PutVarint64(dst, iter->second);  // file number
    75    }
    76  
    77    for (size_t i = 0; i < new_files_.size(); i++) {
    78      const FileMetaData& f = new_files_[i].second;
    79      PutVarint32(dst, kNewFile);
    80      PutVarint32(dst, new_files_[i].first);  // level
    81      PutVarint64(dst, f.number);
    82      PutVarint64(dst, f.file_size);
    83      PutLengthPrefixedSlice(dst, f.smallest.Encode());
    84      PutLengthPrefixedSlice(dst, f.largest.Encode());
    85    }
    86  }
    87  
    88  static bool GetInternalKey(Slice* input, InternalKey* dst) {
    89    Slice str;
    90    if (GetLengthPrefixedSlice(input, &str)) {
    91      dst->DecodeFrom(str);
    92      return true;
    93    } else {
    94      return false;
    95    }
    96  }
    97  
    98  static bool GetLevel(Slice* input, int* level) {
    99    uint32_t v;
   100    if (GetVarint32(input, &v) &&
   101        v < config::kNumLevels) {
   102      *level = v;
   103      return true;
   104    } else {
   105      return false;
   106    }
   107  }
   108  
   109  Status VersionEdit::DecodeFrom(const Slice& src) {
   110    Clear();
   111    Slice input = src;
   112    const char* msg = NULL;
   113    uint32_t tag;
   114  
   115    // Temporary storage for parsing
   116    int level;
   117    uint64_t number;
   118    FileMetaData f;
   119    Slice str;
   120    InternalKey key;
   121  
   122    while (msg == NULL && GetVarint32(&input, &tag)) {
   123      switch (tag) {
   124        case kComparator:
   125          if (GetLengthPrefixedSlice(&input, &str)) {
   126            comparator_ = str.ToString();
   127            has_comparator_ = true;
   128          } else {
   129            msg = "comparator name";
   130          }
   131          break;
   132  
   133        case kLogNumber:
   134          if (GetVarint64(&input, &log_number_)) {
   135            has_log_number_ = true;
   136          } else {
   137            msg = "log number";
   138          }
   139          break;
   140  
   141        case kPrevLogNumber:
   142          if (GetVarint64(&input, &prev_log_number_)) {
   143            has_prev_log_number_ = true;
   144          } else {
   145            msg = "previous log number";
   146          }
   147          break;
   148  
   149        case kNextFileNumber:
   150          if (GetVarint64(&input, &next_file_number_)) {
   151            has_next_file_number_ = true;
   152          } else {
   153            msg = "next file number";
   154          }
   155          break;
   156  
   157        case kLastSequence:
   158          if (GetVarint64(&input, &last_sequence_)) {
   159            has_last_sequence_ = true;
   160          } else {
   161            msg = "last sequence number";
   162          }
   163          break;
   164  
   165        case kCompactPointer:
   166          if (GetLevel(&input, &level) &&
   167              GetInternalKey(&input, &key)) {
   168            compact_pointers_.push_back(std::make_pair(level, key));
   169          } else {
   170            msg = "compaction pointer";
   171          }
   172          break;
   173  
   174        case kDeletedFile:
   175          if (GetLevel(&input, &level) &&
   176              GetVarint64(&input, &number)) {
   177            deleted_files_.insert(std::make_pair(level, number));
   178          } else {
   179            msg = "deleted file";
   180          }
   181          break;
   182  
   183        case kNewFile:
   184          if (GetLevel(&input, &level) &&
   185              GetVarint64(&input, &f.number) &&
   186              GetVarint64(&input, &f.file_size) &&
   187              GetInternalKey(&input, &f.smallest) &&
   188              GetInternalKey(&input, &f.largest)) {
   189            new_files_.push_back(std::make_pair(level, f));
   190          } else {
   191            msg = "new-file entry";
   192          }
   193          break;
   194  
   195        default:
   196          msg = "unknown tag";
   197          break;
   198      }
   199    }
   200  
   201    if (msg == NULL && !input.empty()) {
   202      msg = "invalid tag";
   203    }
   204  
   205    Status result;
   206    if (msg != NULL) {
   207      result = Status::Corruption("VersionEdit", msg);
   208    }
   209    return result;
   210  }
   211  
   212  std::string VersionEdit::DebugString() const {
   213    std::string r;
   214    r.append("VersionEdit {");
   215    if (has_comparator_) {
   216      r.append("\n  Comparator: ");
   217      r.append(comparator_);
   218    }
   219    if (has_log_number_) {
   220      r.append("\n  LogNumber: ");
   221      AppendNumberTo(&r, log_number_);
   222    }
   223    if (has_prev_log_number_) {
   224      r.append("\n  PrevLogNumber: ");
   225      AppendNumberTo(&r, prev_log_number_);
   226    }
   227    if (has_next_file_number_) {
   228      r.append("\n  NextFile: ");
   229      AppendNumberTo(&r, next_file_number_);
   230    }
   231    if (has_last_sequence_) {
   232      r.append("\n  LastSeq: ");
   233      AppendNumberTo(&r, last_sequence_);
   234    }
   235    for (size_t i = 0; i < compact_pointers_.size(); i++) {
   236      r.append("\n  CompactPointer: ");
   237      AppendNumberTo(&r, compact_pointers_[i].first);
   238      r.append(" ");
   239      r.append(compact_pointers_[i].second.DebugString());
   240    }
   241    for (DeletedFileSet::const_iterator iter = deleted_files_.begin();
   242         iter != deleted_files_.end();
   243         ++iter) {
   244      r.append("\n  DeleteFile: ");
   245      AppendNumberTo(&r, iter->first);
   246      r.append(" ");
   247      AppendNumberTo(&r, iter->second);
   248    }
   249    for (size_t i = 0; i < new_files_.size(); i++) {
   250      const FileMetaData& f = new_files_[i].second;
   251      r.append("\n  AddFile: ");
   252      AppendNumberTo(&r, new_files_[i].first);
   253      r.append(" ");
   254      AppendNumberTo(&r, f.number);
   255      r.append(" ");
   256      AppendNumberTo(&r, f.file_size);
   257      r.append(" ");
   258      r.append(f.smallest.DebugString());
   259      r.append(" .. ");
   260      r.append(f.largest.DebugString());
   261    }
   262    r.append("\n}\n");
   263    return r;
   264  }
   265  
   266  }  // namespace leveldb