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