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.
5 #include "db/version_edit.h"
7 #include "db/version_set.h"
8 #include "util/coding.h"
12 // Tag numbers for serialized VersionEdit. These numbers are written to
13 // disk and should not be changed.
22 // 8 was used for large value refs
26 void VersionEdit::Clear() {
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();
41 void VersionEdit::EncodeTo(std::string* dst) const {
42 if (has_comparator_) {
43 PutVarint32(dst, kComparator);
44 PutLengthPrefixedSlice(dst, comparator_);
46 if (has_log_number_) {
47 PutVarint32(dst, kLogNumber);
48 PutVarint64(dst, log_number_);
50 if (has_prev_log_number_) {
51 PutVarint32(dst, kPrevLogNumber);
52 PutVarint64(dst, prev_log_number_);
54 if (has_next_file_number_) {
55 PutVarint32(dst, kNextFileNumber);
56 PutVarint64(dst, next_file_number_);
58 if (has_last_sequence_) {
59 PutVarint32(dst, kLastSequence);
60 PutVarint64(dst, last_sequence_);
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());
69 for (DeletedFileSet::const_iterator iter = deleted_files_.begin();
70 iter != deleted_files_.end();
72 PutVarint32(dst, kDeletedFile);
73 PutVarint32(dst, iter->first); // level
74 PutVarint64(dst, iter->second); // file number
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());
88 static bool GetInternalKey(Slice* input, InternalKey* dst) {
90 if (GetLengthPrefixedSlice(input, &str)) {
98 static bool GetLevel(Slice* input, int* level) {
100 if (GetVarint32(input, &v) &&
101 v < config::kNumLevels) {
109 Status VersionEdit::DecodeFrom(const Slice& src) {
112 const char* msg = NULL;
115 // Temporary storage for parsing
122 while (msg == NULL && GetVarint32(&input, &tag)) {
125 if (GetLengthPrefixedSlice(&input, &str)) {
126 comparator_ = str.ToString();
127 has_comparator_ = true;
129 msg = "comparator name";
134 if (GetVarint64(&input, &log_number_)) {
135 has_log_number_ = true;
142 if (GetVarint64(&input, &prev_log_number_)) {
143 has_prev_log_number_ = true;
145 msg = "previous log number";
149 case kNextFileNumber:
150 if (GetVarint64(&input, &next_file_number_)) {
151 has_next_file_number_ = true;
153 msg = "next file number";
158 if (GetVarint64(&input, &last_sequence_)) {
159 has_last_sequence_ = true;
161 msg = "last sequence number";
165 case kCompactPointer:
166 if (GetLevel(&input, &level) &&
167 GetInternalKey(&input, &key)) {
168 compact_pointers_.push_back(std::make_pair(level, key));
170 msg = "compaction pointer";
175 if (GetLevel(&input, &level) &&
176 GetVarint64(&input, &number)) {
177 deleted_files_.insert(std::make_pair(level, number));
179 msg = "deleted file";
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));
191 msg = "new-file entry";
201 if (msg == NULL && !input.empty()) {
207 result = Status::Corruption("VersionEdit", msg);
212 std::string VersionEdit::DebugString() const {
214 r.append("VersionEdit {");
215 if (has_comparator_) {
216 r.append("\n Comparator: ");
217 r.append(comparator_);
219 if (has_log_number_) {
220 r.append("\n LogNumber: ");
221 AppendNumberTo(&r, log_number_);
223 if (has_prev_log_number_) {
224 r.append("\n PrevLogNumber: ");
225 AppendNumberTo(&r, prev_log_number_);
227 if (has_next_file_number_) {
228 r.append("\n NextFile: ");
229 AppendNumberTo(&r, next_file_number_);
231 if (has_last_sequence_) {
232 r.append("\n LastSeq: ");
233 AppendNumberTo(&r, last_sequence_);
235 for (size_t i = 0; i < compact_pointers_.size(); i++) {
236 r.append("\n CompactPointer: ");
237 AppendNumberTo(&r, compact_pointers_[i].first);
239 r.append(compact_pointers_[i].second.DebugString());
241 for (DeletedFileSet::const_iterator iter = deleted_files_.begin();
242 iter != deleted_files_.end();
244 r.append("\n DeleteFile: ");
245 AppendNumberTo(&r, iter->first);
247 AppendNumberTo(&r, iter->second);
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);
254 AppendNumberTo(&r, f.number);
256 AppendNumberTo(&r, f.file_size);
258 r.append(f.smallest.DebugString());
260 r.append(f.largest.DebugString());
266 } // namespace leveldb