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