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