xref: /aosp_15_r20/external/leveldb/db/version_set.h (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 // The representation of a DBImpl consists of a set of Versions.  The
6*9507f98cSAndroid Build Coastguard Worker // newest version is called "current".  Older versions may be kept
7*9507f98cSAndroid Build Coastguard Worker // around to provide a consistent view to live iterators.
8*9507f98cSAndroid Build Coastguard Worker //
9*9507f98cSAndroid Build Coastguard Worker // Each Version keeps track of a set of Table files per level.  The
10*9507f98cSAndroid Build Coastguard Worker // entire set of versions is maintained in a VersionSet.
11*9507f98cSAndroid Build Coastguard Worker //
12*9507f98cSAndroid Build Coastguard Worker // Version,VersionSet are thread-compatible, but require external
13*9507f98cSAndroid Build Coastguard Worker // synchronization on all accesses.
14*9507f98cSAndroid Build Coastguard Worker 
15*9507f98cSAndroid Build Coastguard Worker #ifndef STORAGE_LEVELDB_DB_VERSION_SET_H_
16*9507f98cSAndroid Build Coastguard Worker #define STORAGE_LEVELDB_DB_VERSION_SET_H_
17*9507f98cSAndroid Build Coastguard Worker 
18*9507f98cSAndroid Build Coastguard Worker #include <map>
19*9507f98cSAndroid Build Coastguard Worker #include <set>
20*9507f98cSAndroid Build Coastguard Worker #include <vector>
21*9507f98cSAndroid Build Coastguard Worker 
22*9507f98cSAndroid Build Coastguard Worker #include "db/dbformat.h"
23*9507f98cSAndroid Build Coastguard Worker #include "db/version_edit.h"
24*9507f98cSAndroid Build Coastguard Worker #include "port/port.h"
25*9507f98cSAndroid Build Coastguard Worker #include "port/thread_annotations.h"
26*9507f98cSAndroid Build Coastguard Worker 
27*9507f98cSAndroid Build Coastguard Worker namespace leveldb {
28*9507f98cSAndroid Build Coastguard Worker 
29*9507f98cSAndroid Build Coastguard Worker namespace log {
30*9507f98cSAndroid Build Coastguard Worker class Writer;
31*9507f98cSAndroid Build Coastguard Worker }
32*9507f98cSAndroid Build Coastguard Worker 
33*9507f98cSAndroid Build Coastguard Worker class Compaction;
34*9507f98cSAndroid Build Coastguard Worker class Iterator;
35*9507f98cSAndroid Build Coastguard Worker class MemTable;
36*9507f98cSAndroid Build Coastguard Worker class TableBuilder;
37*9507f98cSAndroid Build Coastguard Worker class TableCache;
38*9507f98cSAndroid Build Coastguard Worker class Version;
39*9507f98cSAndroid Build Coastguard Worker class VersionSet;
40*9507f98cSAndroid Build Coastguard Worker class WritableFile;
41*9507f98cSAndroid Build Coastguard Worker 
42*9507f98cSAndroid Build Coastguard Worker // Return the smallest index i such that files[i]->largest >= key.
43*9507f98cSAndroid Build Coastguard Worker // Return files.size() if there is no such file.
44*9507f98cSAndroid Build Coastguard Worker // REQUIRES: "files" contains a sorted list of non-overlapping files.
45*9507f98cSAndroid Build Coastguard Worker int FindFile(const InternalKeyComparator& icmp,
46*9507f98cSAndroid Build Coastguard Worker              const std::vector<FileMetaData*>& files, const Slice& key);
47*9507f98cSAndroid Build Coastguard Worker 
48*9507f98cSAndroid Build Coastguard Worker // Returns true iff some file in "files" overlaps the user key range
49*9507f98cSAndroid Build Coastguard Worker // [*smallest,*largest].
50*9507f98cSAndroid Build Coastguard Worker // smallest==nullptr represents a key smaller than all keys in the DB.
51*9507f98cSAndroid Build Coastguard Worker // largest==nullptr represents a key largest than all keys in the DB.
52*9507f98cSAndroid Build Coastguard Worker // REQUIRES: If disjoint_sorted_files, files[] contains disjoint ranges
53*9507f98cSAndroid Build Coastguard Worker //           in sorted order.
54*9507f98cSAndroid Build Coastguard Worker bool SomeFileOverlapsRange(const InternalKeyComparator& icmp,
55*9507f98cSAndroid Build Coastguard Worker                            bool disjoint_sorted_files,
56*9507f98cSAndroid Build Coastguard Worker                            const std::vector<FileMetaData*>& files,
57*9507f98cSAndroid Build Coastguard Worker                            const Slice* smallest_user_key,
58*9507f98cSAndroid Build Coastguard Worker                            const Slice* largest_user_key);
59*9507f98cSAndroid Build Coastguard Worker 
60*9507f98cSAndroid Build Coastguard Worker class Version {
61*9507f98cSAndroid Build Coastguard Worker  public:
62*9507f98cSAndroid Build Coastguard Worker   // Lookup the value for key.  If found, store it in *val and
63*9507f98cSAndroid Build Coastguard Worker   // return OK.  Else return a non-OK status.  Fills *stats.
64*9507f98cSAndroid Build Coastguard Worker   // REQUIRES: lock is not held
65*9507f98cSAndroid Build Coastguard Worker   struct GetStats {
66*9507f98cSAndroid Build Coastguard Worker     FileMetaData* seek_file;
67*9507f98cSAndroid Build Coastguard Worker     int seek_file_level;
68*9507f98cSAndroid Build Coastguard Worker   };
69*9507f98cSAndroid Build Coastguard Worker 
70*9507f98cSAndroid Build Coastguard Worker   // Append to *iters a sequence of iterators that will
71*9507f98cSAndroid Build Coastguard Worker   // yield the contents of this Version when merged together.
72*9507f98cSAndroid Build Coastguard Worker   // REQUIRES: This version has been saved (see VersionSet::SaveTo)
73*9507f98cSAndroid Build Coastguard Worker   void AddIterators(const ReadOptions&, std::vector<Iterator*>* iters);
74*9507f98cSAndroid Build Coastguard Worker 
75*9507f98cSAndroid Build Coastguard Worker   Status Get(const ReadOptions&, const LookupKey& key, std::string* val,
76*9507f98cSAndroid Build Coastguard Worker              GetStats* stats);
77*9507f98cSAndroid Build Coastguard Worker 
78*9507f98cSAndroid Build Coastguard Worker   // Adds "stats" into the current state.  Returns true if a new
79*9507f98cSAndroid Build Coastguard Worker   // compaction may need to be triggered, false otherwise.
80*9507f98cSAndroid Build Coastguard Worker   // REQUIRES: lock is held
81*9507f98cSAndroid Build Coastguard Worker   bool UpdateStats(const GetStats& stats);
82*9507f98cSAndroid Build Coastguard Worker 
83*9507f98cSAndroid Build Coastguard Worker   // Record a sample of bytes read at the specified internal key.
84*9507f98cSAndroid Build Coastguard Worker   // Samples are taken approximately once every config::kReadBytesPeriod
85*9507f98cSAndroid Build Coastguard Worker   // bytes.  Returns true if a new compaction may need to be triggered.
86*9507f98cSAndroid Build Coastguard Worker   // REQUIRES: lock is held
87*9507f98cSAndroid Build Coastguard Worker   bool RecordReadSample(Slice key);
88*9507f98cSAndroid Build Coastguard Worker 
89*9507f98cSAndroid Build Coastguard Worker   // Reference count management (so Versions do not disappear out from
90*9507f98cSAndroid Build Coastguard Worker   // under live iterators)
91*9507f98cSAndroid Build Coastguard Worker   void Ref();
92*9507f98cSAndroid Build Coastguard Worker   void Unref();
93*9507f98cSAndroid Build Coastguard Worker 
94*9507f98cSAndroid Build Coastguard Worker   void GetOverlappingInputs(
95*9507f98cSAndroid Build Coastguard Worker       int level,
96*9507f98cSAndroid Build Coastguard Worker       const InternalKey* begin,  // nullptr means before all keys
97*9507f98cSAndroid Build Coastguard Worker       const InternalKey* end,    // nullptr means after all keys
98*9507f98cSAndroid Build Coastguard Worker       std::vector<FileMetaData*>* inputs);
99*9507f98cSAndroid Build Coastguard Worker 
100*9507f98cSAndroid Build Coastguard Worker   // Returns true iff some file in the specified level overlaps
101*9507f98cSAndroid Build Coastguard Worker   // some part of [*smallest_user_key,*largest_user_key].
102*9507f98cSAndroid Build Coastguard Worker   // smallest_user_key==nullptr represents a key smaller than all the DB's keys.
103*9507f98cSAndroid Build Coastguard Worker   // largest_user_key==nullptr represents a key largest than all the DB's keys.
104*9507f98cSAndroid Build Coastguard Worker   bool OverlapInLevel(int level, const Slice* smallest_user_key,
105*9507f98cSAndroid Build Coastguard Worker                       const Slice* largest_user_key);
106*9507f98cSAndroid Build Coastguard Worker 
107*9507f98cSAndroid Build Coastguard Worker   // Return the level at which we should place a new memtable compaction
108*9507f98cSAndroid Build Coastguard Worker   // result that covers the range [smallest_user_key,largest_user_key].
109*9507f98cSAndroid Build Coastguard Worker   int PickLevelForMemTableOutput(const Slice& smallest_user_key,
110*9507f98cSAndroid Build Coastguard Worker                                  const Slice& largest_user_key);
111*9507f98cSAndroid Build Coastguard Worker 
NumFiles(int level)112*9507f98cSAndroid Build Coastguard Worker   int NumFiles(int level) const { return files_[level].size(); }
113*9507f98cSAndroid Build Coastguard Worker 
114*9507f98cSAndroid Build Coastguard Worker   // Return a human readable string that describes this version's contents.
115*9507f98cSAndroid Build Coastguard Worker   std::string DebugString() const;
116*9507f98cSAndroid Build Coastguard Worker 
117*9507f98cSAndroid Build Coastguard Worker  private:
118*9507f98cSAndroid Build Coastguard Worker   friend class Compaction;
119*9507f98cSAndroid Build Coastguard Worker   friend class VersionSet;
120*9507f98cSAndroid Build Coastguard Worker 
121*9507f98cSAndroid Build Coastguard Worker   class LevelFileNumIterator;
122*9507f98cSAndroid Build Coastguard Worker 
Version(VersionSet * vset)123*9507f98cSAndroid Build Coastguard Worker   explicit Version(VersionSet* vset)
124*9507f98cSAndroid Build Coastguard Worker       : vset_(vset),
125*9507f98cSAndroid Build Coastguard Worker         next_(this),
126*9507f98cSAndroid Build Coastguard Worker         prev_(this),
127*9507f98cSAndroid Build Coastguard Worker         refs_(0),
128*9507f98cSAndroid Build Coastguard Worker         file_to_compact_(nullptr),
129*9507f98cSAndroid Build Coastguard Worker         file_to_compact_level_(-1),
130*9507f98cSAndroid Build Coastguard Worker         compaction_score_(-1),
131*9507f98cSAndroid Build Coastguard Worker         compaction_level_(-1) {}
132*9507f98cSAndroid Build Coastguard Worker 
133*9507f98cSAndroid Build Coastguard Worker   Version(const Version&) = delete;
134*9507f98cSAndroid Build Coastguard Worker   Version& operator=(const Version&) = delete;
135*9507f98cSAndroid Build Coastguard Worker 
136*9507f98cSAndroid Build Coastguard Worker   ~Version();
137*9507f98cSAndroid Build Coastguard Worker 
138*9507f98cSAndroid Build Coastguard Worker   Iterator* NewConcatenatingIterator(const ReadOptions&, int level) const;
139*9507f98cSAndroid Build Coastguard Worker 
140*9507f98cSAndroid Build Coastguard Worker   // Call func(arg, level, f) for every file that overlaps user_key in
141*9507f98cSAndroid Build Coastguard Worker   // order from newest to oldest.  If an invocation of func returns
142*9507f98cSAndroid Build Coastguard Worker   // false, makes no more calls.
143*9507f98cSAndroid Build Coastguard Worker   //
144*9507f98cSAndroid Build Coastguard Worker   // REQUIRES: user portion of internal_key == user_key.
145*9507f98cSAndroid Build Coastguard Worker   void ForEachOverlapping(Slice user_key, Slice internal_key, void* arg,
146*9507f98cSAndroid Build Coastguard Worker                           bool (*func)(void*, int, FileMetaData*));
147*9507f98cSAndroid Build Coastguard Worker 
148*9507f98cSAndroid Build Coastguard Worker   VersionSet* vset_;  // VersionSet to which this Version belongs
149*9507f98cSAndroid Build Coastguard Worker   Version* next_;     // Next version in linked list
150*9507f98cSAndroid Build Coastguard Worker   Version* prev_;     // Previous version in linked list
151*9507f98cSAndroid Build Coastguard Worker   int refs_;          // Number of live refs to this version
152*9507f98cSAndroid Build Coastguard Worker 
153*9507f98cSAndroid Build Coastguard Worker   // List of files per level
154*9507f98cSAndroid Build Coastguard Worker   std::vector<FileMetaData*> files_[config::kNumLevels];
155*9507f98cSAndroid Build Coastguard Worker 
156*9507f98cSAndroid Build Coastguard Worker   // Next file to compact based on seek stats.
157*9507f98cSAndroid Build Coastguard Worker   FileMetaData* file_to_compact_;
158*9507f98cSAndroid Build Coastguard Worker   int file_to_compact_level_;
159*9507f98cSAndroid Build Coastguard Worker 
160*9507f98cSAndroid Build Coastguard Worker   // Level that should be compacted next and its compaction score.
161*9507f98cSAndroid Build Coastguard Worker   // Score < 1 means compaction is not strictly needed.  These fields
162*9507f98cSAndroid Build Coastguard Worker   // are initialized by Finalize().
163*9507f98cSAndroid Build Coastguard Worker   double compaction_score_;
164*9507f98cSAndroid Build Coastguard Worker   int compaction_level_;
165*9507f98cSAndroid Build Coastguard Worker };
166*9507f98cSAndroid Build Coastguard Worker 
167*9507f98cSAndroid Build Coastguard Worker class VersionSet {
168*9507f98cSAndroid Build Coastguard Worker  public:
169*9507f98cSAndroid Build Coastguard Worker   VersionSet(const std::string& dbname, const Options* options,
170*9507f98cSAndroid Build Coastguard Worker              TableCache* table_cache, const InternalKeyComparator*);
171*9507f98cSAndroid Build Coastguard Worker   VersionSet(const VersionSet&) = delete;
172*9507f98cSAndroid Build Coastguard Worker   VersionSet& operator=(const VersionSet&) = delete;
173*9507f98cSAndroid Build Coastguard Worker 
174*9507f98cSAndroid Build Coastguard Worker   ~VersionSet();
175*9507f98cSAndroid Build Coastguard Worker 
176*9507f98cSAndroid Build Coastguard Worker   // Apply *edit to the current version to form a new descriptor that
177*9507f98cSAndroid Build Coastguard Worker   // is both saved to persistent state and installed as the new
178*9507f98cSAndroid Build Coastguard Worker   // current version.  Will release *mu while actually writing to the file.
179*9507f98cSAndroid Build Coastguard Worker   // REQUIRES: *mu is held on entry.
180*9507f98cSAndroid Build Coastguard Worker   // REQUIRES: no other thread concurrently calls LogAndApply()
181*9507f98cSAndroid Build Coastguard Worker   Status LogAndApply(VersionEdit* edit, port::Mutex* mu)
182*9507f98cSAndroid Build Coastguard Worker       EXCLUSIVE_LOCKS_REQUIRED(mu);
183*9507f98cSAndroid Build Coastguard Worker 
184*9507f98cSAndroid Build Coastguard Worker   // Recover the last saved descriptor from persistent storage.
185*9507f98cSAndroid Build Coastguard Worker   Status Recover(bool* save_manifest);
186*9507f98cSAndroid Build Coastguard Worker 
187*9507f98cSAndroid Build Coastguard Worker   // Return the current version.
current()188*9507f98cSAndroid Build Coastguard Worker   Version* current() const { return current_; }
189*9507f98cSAndroid Build Coastguard Worker 
190*9507f98cSAndroid Build Coastguard Worker   // Return the current manifest file number
ManifestFileNumber()191*9507f98cSAndroid Build Coastguard Worker   uint64_t ManifestFileNumber() const { return manifest_file_number_; }
192*9507f98cSAndroid Build Coastguard Worker 
193*9507f98cSAndroid Build Coastguard Worker   // Allocate and return a new file number
NewFileNumber()194*9507f98cSAndroid Build Coastguard Worker   uint64_t NewFileNumber() { return next_file_number_++; }
195*9507f98cSAndroid Build Coastguard Worker 
196*9507f98cSAndroid Build Coastguard Worker   // Arrange to reuse "file_number" unless a newer file number has
197*9507f98cSAndroid Build Coastguard Worker   // already been allocated.
198*9507f98cSAndroid Build Coastguard Worker   // REQUIRES: "file_number" was returned by a call to NewFileNumber().
ReuseFileNumber(uint64_t file_number)199*9507f98cSAndroid Build Coastguard Worker   void ReuseFileNumber(uint64_t file_number) {
200*9507f98cSAndroid Build Coastguard Worker     if (next_file_number_ == file_number + 1) {
201*9507f98cSAndroid Build Coastguard Worker       next_file_number_ = file_number;
202*9507f98cSAndroid Build Coastguard Worker     }
203*9507f98cSAndroid Build Coastguard Worker   }
204*9507f98cSAndroid Build Coastguard Worker 
205*9507f98cSAndroid Build Coastguard Worker   // Return the number of Table files at the specified level.
206*9507f98cSAndroid Build Coastguard Worker   int NumLevelFiles(int level) const;
207*9507f98cSAndroid Build Coastguard Worker 
208*9507f98cSAndroid Build Coastguard Worker   // Return the combined file size of all files at the specified level.
209*9507f98cSAndroid Build Coastguard Worker   int64_t NumLevelBytes(int level) const;
210*9507f98cSAndroid Build Coastguard Worker 
211*9507f98cSAndroid Build Coastguard Worker   // Return the last sequence number.
LastSequence()212*9507f98cSAndroid Build Coastguard Worker   uint64_t LastSequence() const { return last_sequence_; }
213*9507f98cSAndroid Build Coastguard Worker 
214*9507f98cSAndroid Build Coastguard Worker   // Set the last sequence number to s.
SetLastSequence(uint64_t s)215*9507f98cSAndroid Build Coastguard Worker   void SetLastSequence(uint64_t s) {
216*9507f98cSAndroid Build Coastguard Worker     assert(s >= last_sequence_);
217*9507f98cSAndroid Build Coastguard Worker     last_sequence_ = s;
218*9507f98cSAndroid Build Coastguard Worker   }
219*9507f98cSAndroid Build Coastguard Worker 
220*9507f98cSAndroid Build Coastguard Worker   // Mark the specified file number as used.
221*9507f98cSAndroid Build Coastguard Worker   void MarkFileNumberUsed(uint64_t number);
222*9507f98cSAndroid Build Coastguard Worker 
223*9507f98cSAndroid Build Coastguard Worker   // Return the current log file number.
LogNumber()224*9507f98cSAndroid Build Coastguard Worker   uint64_t LogNumber() const { return log_number_; }
225*9507f98cSAndroid Build Coastguard Worker 
226*9507f98cSAndroid Build Coastguard Worker   // Return the log file number for the log file that is currently
227*9507f98cSAndroid Build Coastguard Worker   // being compacted, or zero if there is no such log file.
PrevLogNumber()228*9507f98cSAndroid Build Coastguard Worker   uint64_t PrevLogNumber() const { return prev_log_number_; }
229*9507f98cSAndroid Build Coastguard Worker 
230*9507f98cSAndroid Build Coastguard Worker   // Pick level and inputs for a new compaction.
231*9507f98cSAndroid Build Coastguard Worker   // Returns nullptr if there is no compaction to be done.
232*9507f98cSAndroid Build Coastguard Worker   // Otherwise returns a pointer to a heap-allocated object that
233*9507f98cSAndroid Build Coastguard Worker   // describes the compaction.  Caller should delete the result.
234*9507f98cSAndroid Build Coastguard Worker   Compaction* PickCompaction();
235*9507f98cSAndroid Build Coastguard Worker 
236*9507f98cSAndroid Build Coastguard Worker   // Return a compaction object for compacting the range [begin,end] in
237*9507f98cSAndroid Build Coastguard Worker   // the specified level.  Returns nullptr if there is nothing in that
238*9507f98cSAndroid Build Coastguard Worker   // level that overlaps the specified range.  Caller should delete
239*9507f98cSAndroid Build Coastguard Worker   // the result.
240*9507f98cSAndroid Build Coastguard Worker   Compaction* CompactRange(int level, const InternalKey* begin,
241*9507f98cSAndroid Build Coastguard Worker                            const InternalKey* end);
242*9507f98cSAndroid Build Coastguard Worker 
243*9507f98cSAndroid Build Coastguard Worker   // Return the maximum overlapping data (in bytes) at next level for any
244*9507f98cSAndroid Build Coastguard Worker   // file at a level >= 1.
245*9507f98cSAndroid Build Coastguard Worker   int64_t MaxNextLevelOverlappingBytes();
246*9507f98cSAndroid Build Coastguard Worker 
247*9507f98cSAndroid Build Coastguard Worker   // Create an iterator that reads over the compaction inputs for "*c".
248*9507f98cSAndroid Build Coastguard Worker   // The caller should delete the iterator when no longer needed.
249*9507f98cSAndroid Build Coastguard Worker   Iterator* MakeInputIterator(Compaction* c);
250*9507f98cSAndroid Build Coastguard Worker 
251*9507f98cSAndroid Build Coastguard Worker   // Returns true iff some level needs a compaction.
NeedsCompaction()252*9507f98cSAndroid Build Coastguard Worker   bool NeedsCompaction() const {
253*9507f98cSAndroid Build Coastguard Worker     Version* v = current_;
254*9507f98cSAndroid Build Coastguard Worker     return (v->compaction_score_ >= 1) || (v->file_to_compact_ != nullptr);
255*9507f98cSAndroid Build Coastguard Worker   }
256*9507f98cSAndroid Build Coastguard Worker 
257*9507f98cSAndroid Build Coastguard Worker   // Add all files listed in any live version to *live.
258*9507f98cSAndroid Build Coastguard Worker   // May also mutate some internal state.
259*9507f98cSAndroid Build Coastguard Worker   void AddLiveFiles(std::set<uint64_t>* live);
260*9507f98cSAndroid Build Coastguard Worker 
261*9507f98cSAndroid Build Coastguard Worker   // Return the approximate offset in the database of the data for
262*9507f98cSAndroid Build Coastguard Worker   // "key" as of version "v".
263*9507f98cSAndroid Build Coastguard Worker   uint64_t ApproximateOffsetOf(Version* v, const InternalKey& key);
264*9507f98cSAndroid Build Coastguard Worker 
265*9507f98cSAndroid Build Coastguard Worker   // Return a human-readable short (single-line) summary of the number
266*9507f98cSAndroid Build Coastguard Worker   // of files per level.  Uses *scratch as backing store.
267*9507f98cSAndroid Build Coastguard Worker   struct LevelSummaryStorage {
268*9507f98cSAndroid Build Coastguard Worker     char buffer[100];
269*9507f98cSAndroid Build Coastguard Worker   };
270*9507f98cSAndroid Build Coastguard Worker   const char* LevelSummary(LevelSummaryStorage* scratch) const;
271*9507f98cSAndroid Build Coastguard Worker 
272*9507f98cSAndroid Build Coastguard Worker  private:
273*9507f98cSAndroid Build Coastguard Worker   class Builder;
274*9507f98cSAndroid Build Coastguard Worker 
275*9507f98cSAndroid Build Coastguard Worker   friend class Compaction;
276*9507f98cSAndroid Build Coastguard Worker   friend class Version;
277*9507f98cSAndroid Build Coastguard Worker 
278*9507f98cSAndroid Build Coastguard Worker   bool ReuseManifest(const std::string& dscname, const std::string& dscbase);
279*9507f98cSAndroid Build Coastguard Worker 
280*9507f98cSAndroid Build Coastguard Worker   void Finalize(Version* v);
281*9507f98cSAndroid Build Coastguard Worker 
282*9507f98cSAndroid Build Coastguard Worker   void GetRange(const std::vector<FileMetaData*>& inputs, InternalKey* smallest,
283*9507f98cSAndroid Build Coastguard Worker                 InternalKey* largest);
284*9507f98cSAndroid Build Coastguard Worker 
285*9507f98cSAndroid Build Coastguard Worker   void GetRange2(const std::vector<FileMetaData*>& inputs1,
286*9507f98cSAndroid Build Coastguard Worker                  const std::vector<FileMetaData*>& inputs2,
287*9507f98cSAndroid Build Coastguard Worker                  InternalKey* smallest, InternalKey* largest);
288*9507f98cSAndroid Build Coastguard Worker 
289*9507f98cSAndroid Build Coastguard Worker   void SetupOtherInputs(Compaction* c);
290*9507f98cSAndroid Build Coastguard Worker 
291*9507f98cSAndroid Build Coastguard Worker   // Save current contents to *log
292*9507f98cSAndroid Build Coastguard Worker   Status WriteSnapshot(log::Writer* log);
293*9507f98cSAndroid Build Coastguard Worker 
294*9507f98cSAndroid Build Coastguard Worker   void AppendVersion(Version* v);
295*9507f98cSAndroid Build Coastguard Worker 
296*9507f98cSAndroid Build Coastguard Worker   Env* const env_;
297*9507f98cSAndroid Build Coastguard Worker   const std::string dbname_;
298*9507f98cSAndroid Build Coastguard Worker   const Options* const options_;
299*9507f98cSAndroid Build Coastguard Worker   TableCache* const table_cache_;
300*9507f98cSAndroid Build Coastguard Worker   const InternalKeyComparator icmp_;
301*9507f98cSAndroid Build Coastguard Worker   uint64_t next_file_number_;
302*9507f98cSAndroid Build Coastguard Worker   uint64_t manifest_file_number_;
303*9507f98cSAndroid Build Coastguard Worker   uint64_t last_sequence_;
304*9507f98cSAndroid Build Coastguard Worker   uint64_t log_number_;
305*9507f98cSAndroid Build Coastguard Worker   uint64_t prev_log_number_;  // 0 or backing store for memtable being compacted
306*9507f98cSAndroid Build Coastguard Worker 
307*9507f98cSAndroid Build Coastguard Worker   // Opened lazily
308*9507f98cSAndroid Build Coastguard Worker   WritableFile* descriptor_file_;
309*9507f98cSAndroid Build Coastguard Worker   log::Writer* descriptor_log_;
310*9507f98cSAndroid Build Coastguard Worker   Version dummy_versions_;  // Head of circular doubly-linked list of versions.
311*9507f98cSAndroid Build Coastguard Worker   Version* current_;        // == dummy_versions_.prev_
312*9507f98cSAndroid Build Coastguard Worker 
313*9507f98cSAndroid Build Coastguard Worker   // Per-level key at which the next compaction at that level should start.
314*9507f98cSAndroid Build Coastguard Worker   // Either an empty string, or a valid InternalKey.
315*9507f98cSAndroid Build Coastguard Worker   std::string compact_pointer_[config::kNumLevels];
316*9507f98cSAndroid Build Coastguard Worker };
317*9507f98cSAndroid Build Coastguard Worker 
318*9507f98cSAndroid Build Coastguard Worker // A Compaction encapsulates information about a compaction.
319*9507f98cSAndroid Build Coastguard Worker class Compaction {
320*9507f98cSAndroid Build Coastguard Worker  public:
321*9507f98cSAndroid Build Coastguard Worker   ~Compaction();
322*9507f98cSAndroid Build Coastguard Worker 
323*9507f98cSAndroid Build Coastguard Worker   // Return the level that is being compacted.  Inputs from "level"
324*9507f98cSAndroid Build Coastguard Worker   // and "level+1" will be merged to produce a set of "level+1" files.
level()325*9507f98cSAndroid Build Coastguard Worker   int level() const { return level_; }
326*9507f98cSAndroid Build Coastguard Worker 
327*9507f98cSAndroid Build Coastguard Worker   // Return the object that holds the edits to the descriptor done
328*9507f98cSAndroid Build Coastguard Worker   // by this compaction.
edit()329*9507f98cSAndroid Build Coastguard Worker   VersionEdit* edit() { return &edit_; }
330*9507f98cSAndroid Build Coastguard Worker 
331*9507f98cSAndroid Build Coastguard Worker   // "which" must be either 0 or 1
num_input_files(int which)332*9507f98cSAndroid Build Coastguard Worker   int num_input_files(int which) const { return inputs_[which].size(); }
333*9507f98cSAndroid Build Coastguard Worker 
334*9507f98cSAndroid Build Coastguard Worker   // Return the ith input file at "level()+which" ("which" must be 0 or 1).
input(int which,int i)335*9507f98cSAndroid Build Coastguard Worker   FileMetaData* input(int which, int i) const { return inputs_[which][i]; }
336*9507f98cSAndroid Build Coastguard Worker 
337*9507f98cSAndroid Build Coastguard Worker   // Maximum size of files to build during this compaction.
MaxOutputFileSize()338*9507f98cSAndroid Build Coastguard Worker   uint64_t MaxOutputFileSize() const { return max_output_file_size_; }
339*9507f98cSAndroid Build Coastguard Worker 
340*9507f98cSAndroid Build Coastguard Worker   // Is this a trivial compaction that can be implemented by just
341*9507f98cSAndroid Build Coastguard Worker   // moving a single input file to the next level (no merging or splitting)
342*9507f98cSAndroid Build Coastguard Worker   bool IsTrivialMove() const;
343*9507f98cSAndroid Build Coastguard Worker 
344*9507f98cSAndroid Build Coastguard Worker   // Add all inputs to this compaction as delete operations to *edit.
345*9507f98cSAndroid Build Coastguard Worker   void AddInputDeletions(VersionEdit* edit);
346*9507f98cSAndroid Build Coastguard Worker 
347*9507f98cSAndroid Build Coastguard Worker   // Returns true if the information we have available guarantees that
348*9507f98cSAndroid Build Coastguard Worker   // the compaction is producing data in "level+1" for which no data exists
349*9507f98cSAndroid Build Coastguard Worker   // in levels greater than "level+1".
350*9507f98cSAndroid Build Coastguard Worker   bool IsBaseLevelForKey(const Slice& user_key);
351*9507f98cSAndroid Build Coastguard Worker 
352*9507f98cSAndroid Build Coastguard Worker   // Returns true iff we should stop building the current output
353*9507f98cSAndroid Build Coastguard Worker   // before processing "internal_key".
354*9507f98cSAndroid Build Coastguard Worker   bool ShouldStopBefore(const Slice& internal_key);
355*9507f98cSAndroid Build Coastguard Worker 
356*9507f98cSAndroid Build Coastguard Worker   // Release the input version for the compaction, once the compaction
357*9507f98cSAndroid Build Coastguard Worker   // is successful.
358*9507f98cSAndroid Build Coastguard Worker   void ReleaseInputs();
359*9507f98cSAndroid Build Coastguard Worker 
360*9507f98cSAndroid Build Coastguard Worker  private:
361*9507f98cSAndroid Build Coastguard Worker   friend class Version;
362*9507f98cSAndroid Build Coastguard Worker   friend class VersionSet;
363*9507f98cSAndroid Build Coastguard Worker 
364*9507f98cSAndroid Build Coastguard Worker   Compaction(const Options* options, int level);
365*9507f98cSAndroid Build Coastguard Worker 
366*9507f98cSAndroid Build Coastguard Worker   int level_;
367*9507f98cSAndroid Build Coastguard Worker   uint64_t max_output_file_size_;
368*9507f98cSAndroid Build Coastguard Worker   Version* input_version_;
369*9507f98cSAndroid Build Coastguard Worker   VersionEdit edit_;
370*9507f98cSAndroid Build Coastguard Worker 
371*9507f98cSAndroid Build Coastguard Worker   // Each compaction reads inputs from "level_" and "level_+1"
372*9507f98cSAndroid Build Coastguard Worker   std::vector<FileMetaData*> inputs_[2];  // The two sets of inputs
373*9507f98cSAndroid Build Coastguard Worker 
374*9507f98cSAndroid Build Coastguard Worker   // State used to check for number of overlapping grandparent files
375*9507f98cSAndroid Build Coastguard Worker   // (parent == level_ + 1, grandparent == level_ + 2)
376*9507f98cSAndroid Build Coastguard Worker   std::vector<FileMetaData*> grandparents_;
377*9507f98cSAndroid Build Coastguard Worker   size_t grandparent_index_;  // Index in grandparent_starts_
378*9507f98cSAndroid Build Coastguard Worker   bool seen_key_;             // Some output key has been seen
379*9507f98cSAndroid Build Coastguard Worker   int64_t overlapped_bytes_;  // Bytes of overlap between current output
380*9507f98cSAndroid Build Coastguard Worker                               // and grandparent files
381*9507f98cSAndroid Build Coastguard Worker 
382*9507f98cSAndroid Build Coastguard Worker   // State for implementing IsBaseLevelForKey
383*9507f98cSAndroid Build Coastguard Worker 
384*9507f98cSAndroid Build Coastguard Worker   // level_ptrs_ holds indices into input_version_->levels_: our state
385*9507f98cSAndroid Build Coastguard Worker   // is that we are positioned at one of the file ranges for each
386*9507f98cSAndroid Build Coastguard Worker   // higher level than the ones involved in this compaction (i.e. for
387*9507f98cSAndroid Build Coastguard Worker   // all L >= level_ + 2).
388*9507f98cSAndroid Build Coastguard Worker   size_t level_ptrs_[config::kNumLevels];
389*9507f98cSAndroid Build Coastguard Worker };
390*9507f98cSAndroid Build Coastguard Worker 
391*9507f98cSAndroid Build Coastguard Worker }  // namespace leveldb
392*9507f98cSAndroid Build Coastguard Worker 
393*9507f98cSAndroid Build Coastguard Worker #endif  // STORAGE_LEVELDB_DB_VERSION_SET_H_
394