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 #ifndef STORAGE_LEVELDB_DB_DB_IMPL_H_ 6*9507f98cSAndroid Build Coastguard Worker #define STORAGE_LEVELDB_DB_DB_IMPL_H_ 7*9507f98cSAndroid Build Coastguard Worker 8*9507f98cSAndroid Build Coastguard Worker #include <atomic> 9*9507f98cSAndroid Build Coastguard Worker #include <deque> 10*9507f98cSAndroid Build Coastguard Worker #include <set> 11*9507f98cSAndroid Build Coastguard Worker #include <string> 12*9507f98cSAndroid Build Coastguard Worker 13*9507f98cSAndroid Build Coastguard Worker #include "db/dbformat.h" 14*9507f98cSAndroid Build Coastguard Worker #include "db/log_writer.h" 15*9507f98cSAndroid Build Coastguard Worker #include "db/snapshot.h" 16*9507f98cSAndroid Build Coastguard Worker #include "leveldb/db.h" 17*9507f98cSAndroid Build Coastguard Worker #include "leveldb/env.h" 18*9507f98cSAndroid Build Coastguard Worker #include "port/port.h" 19*9507f98cSAndroid Build Coastguard Worker #include "port/thread_annotations.h" 20*9507f98cSAndroid Build Coastguard Worker 21*9507f98cSAndroid Build Coastguard Worker namespace leveldb { 22*9507f98cSAndroid Build Coastguard Worker 23*9507f98cSAndroid Build Coastguard Worker class MemTable; 24*9507f98cSAndroid Build Coastguard Worker class TableCache; 25*9507f98cSAndroid Build Coastguard Worker class Version; 26*9507f98cSAndroid Build Coastguard Worker class VersionEdit; 27*9507f98cSAndroid Build Coastguard Worker class VersionSet; 28*9507f98cSAndroid Build Coastguard Worker 29*9507f98cSAndroid Build Coastguard Worker class DBImpl : public DB { 30*9507f98cSAndroid Build Coastguard Worker public: 31*9507f98cSAndroid Build Coastguard Worker DBImpl(const Options& options, const std::string& dbname); 32*9507f98cSAndroid Build Coastguard Worker 33*9507f98cSAndroid Build Coastguard Worker DBImpl(const DBImpl&) = delete; 34*9507f98cSAndroid Build Coastguard Worker DBImpl& operator=(const DBImpl&) = delete; 35*9507f98cSAndroid Build Coastguard Worker 36*9507f98cSAndroid Build Coastguard Worker ~DBImpl() override; 37*9507f98cSAndroid Build Coastguard Worker 38*9507f98cSAndroid Build Coastguard Worker // Implementations of the DB interface 39*9507f98cSAndroid Build Coastguard Worker Status Put(const WriteOptions&, const Slice& key, 40*9507f98cSAndroid Build Coastguard Worker const Slice& value) override; 41*9507f98cSAndroid Build Coastguard Worker Status Delete(const WriteOptions&, const Slice& key) override; 42*9507f98cSAndroid Build Coastguard Worker Status Write(const WriteOptions& options, WriteBatch* updates) override; 43*9507f98cSAndroid Build Coastguard Worker Status Get(const ReadOptions& options, const Slice& key, 44*9507f98cSAndroid Build Coastguard Worker std::string* value) override; 45*9507f98cSAndroid Build Coastguard Worker Iterator* NewIterator(const ReadOptions&) override; 46*9507f98cSAndroid Build Coastguard Worker const Snapshot* GetSnapshot() override; 47*9507f98cSAndroid Build Coastguard Worker void ReleaseSnapshot(const Snapshot* snapshot) override; 48*9507f98cSAndroid Build Coastguard Worker bool GetProperty(const Slice& property, std::string* value) override; 49*9507f98cSAndroid Build Coastguard Worker void GetApproximateSizes(const Range* range, int n, uint64_t* sizes) override; 50*9507f98cSAndroid Build Coastguard Worker void CompactRange(const Slice* begin, const Slice* end) override; 51*9507f98cSAndroid Build Coastguard Worker 52*9507f98cSAndroid Build Coastguard Worker // Extra methods (for testing) that are not in the public DB interface 53*9507f98cSAndroid Build Coastguard Worker 54*9507f98cSAndroid Build Coastguard Worker // Compact any files in the named level that overlap [*begin,*end] 55*9507f98cSAndroid Build Coastguard Worker void TEST_CompactRange(int level, const Slice* begin, const Slice* end); 56*9507f98cSAndroid Build Coastguard Worker 57*9507f98cSAndroid Build Coastguard Worker // Force current memtable contents to be compacted. 58*9507f98cSAndroid Build Coastguard Worker Status TEST_CompactMemTable(); 59*9507f98cSAndroid Build Coastguard Worker 60*9507f98cSAndroid Build Coastguard Worker // Return an internal iterator over the current state of the database. 61*9507f98cSAndroid Build Coastguard Worker // The keys of this iterator are internal keys (see format.h). 62*9507f98cSAndroid Build Coastguard Worker // The returned iterator should be deleted when no longer needed. 63*9507f98cSAndroid Build Coastguard Worker Iterator* TEST_NewInternalIterator(); 64*9507f98cSAndroid Build Coastguard Worker 65*9507f98cSAndroid Build Coastguard Worker // Return the maximum overlapping data (in bytes) at next level for any 66*9507f98cSAndroid Build Coastguard Worker // file at a level >= 1. 67*9507f98cSAndroid Build Coastguard Worker int64_t TEST_MaxNextLevelOverlappingBytes(); 68*9507f98cSAndroid Build Coastguard Worker 69*9507f98cSAndroid Build Coastguard Worker // Record a sample of bytes read at the specified internal key. 70*9507f98cSAndroid Build Coastguard Worker // Samples are taken approximately once every config::kReadBytesPeriod 71*9507f98cSAndroid Build Coastguard Worker // bytes. 72*9507f98cSAndroid Build Coastguard Worker void RecordReadSample(Slice key); 73*9507f98cSAndroid Build Coastguard Worker 74*9507f98cSAndroid Build Coastguard Worker private: 75*9507f98cSAndroid Build Coastguard Worker friend class DB; 76*9507f98cSAndroid Build Coastguard Worker struct CompactionState; 77*9507f98cSAndroid Build Coastguard Worker struct Writer; 78*9507f98cSAndroid Build Coastguard Worker 79*9507f98cSAndroid Build Coastguard Worker // Information for a manual compaction 80*9507f98cSAndroid Build Coastguard Worker struct ManualCompaction { 81*9507f98cSAndroid Build Coastguard Worker int level; 82*9507f98cSAndroid Build Coastguard Worker bool done; 83*9507f98cSAndroid Build Coastguard Worker const InternalKey* begin; // null means beginning of key range 84*9507f98cSAndroid Build Coastguard Worker const InternalKey* end; // null means end of key range 85*9507f98cSAndroid Build Coastguard Worker InternalKey tmp_storage; // Used to keep track of compaction progress 86*9507f98cSAndroid Build Coastguard Worker }; 87*9507f98cSAndroid Build Coastguard Worker 88*9507f98cSAndroid Build Coastguard Worker // Per level compaction stats. stats_[level] stores the stats for 89*9507f98cSAndroid Build Coastguard Worker // compactions that produced data for the specified "level". 90*9507f98cSAndroid Build Coastguard Worker struct CompactionStats { CompactionStatsCompactionStats91*9507f98cSAndroid Build Coastguard Worker CompactionStats() : micros(0), bytes_read(0), bytes_written(0) {} 92*9507f98cSAndroid Build Coastguard Worker AddCompactionStats93*9507f98cSAndroid Build Coastguard Worker void Add(const CompactionStats& c) { 94*9507f98cSAndroid Build Coastguard Worker this->micros += c.micros; 95*9507f98cSAndroid Build Coastguard Worker this->bytes_read += c.bytes_read; 96*9507f98cSAndroid Build Coastguard Worker this->bytes_written += c.bytes_written; 97*9507f98cSAndroid Build Coastguard Worker } 98*9507f98cSAndroid Build Coastguard Worker 99*9507f98cSAndroid Build Coastguard Worker int64_t micros; 100*9507f98cSAndroid Build Coastguard Worker int64_t bytes_read; 101*9507f98cSAndroid Build Coastguard Worker int64_t bytes_written; 102*9507f98cSAndroid Build Coastguard Worker }; 103*9507f98cSAndroid Build Coastguard Worker 104*9507f98cSAndroid Build Coastguard Worker Iterator* NewInternalIterator(const ReadOptions&, 105*9507f98cSAndroid Build Coastguard Worker SequenceNumber* latest_snapshot, 106*9507f98cSAndroid Build Coastguard Worker uint32_t* seed); 107*9507f98cSAndroid Build Coastguard Worker 108*9507f98cSAndroid Build Coastguard Worker Status NewDB(); 109*9507f98cSAndroid Build Coastguard Worker 110*9507f98cSAndroid Build Coastguard Worker // Recover the descriptor from persistent storage. May do a significant 111*9507f98cSAndroid Build Coastguard Worker // amount of work to recover recently logged updates. Any changes to 112*9507f98cSAndroid Build Coastguard Worker // be made to the descriptor are added to *edit. 113*9507f98cSAndroid Build Coastguard Worker Status Recover(VersionEdit* edit, bool* save_manifest) 114*9507f98cSAndroid Build Coastguard Worker EXCLUSIVE_LOCKS_REQUIRED(mutex_); 115*9507f98cSAndroid Build Coastguard Worker 116*9507f98cSAndroid Build Coastguard Worker void MaybeIgnoreError(Status* s) const; 117*9507f98cSAndroid Build Coastguard Worker 118*9507f98cSAndroid Build Coastguard Worker // Delete any unneeded files and stale in-memory entries. 119*9507f98cSAndroid Build Coastguard Worker void RemoveObsoleteFiles() EXCLUSIVE_LOCKS_REQUIRED(mutex_); 120*9507f98cSAndroid Build Coastguard Worker 121*9507f98cSAndroid Build Coastguard Worker // Compact the in-memory write buffer to disk. Switches to a new 122*9507f98cSAndroid Build Coastguard Worker // log-file/memtable and writes a new descriptor iff successful. 123*9507f98cSAndroid Build Coastguard Worker // Errors are recorded in bg_error_. 124*9507f98cSAndroid Build Coastguard Worker void CompactMemTable() EXCLUSIVE_LOCKS_REQUIRED(mutex_); 125*9507f98cSAndroid Build Coastguard Worker 126*9507f98cSAndroid Build Coastguard Worker Status RecoverLogFile(uint64_t log_number, bool last_log, bool* save_manifest, 127*9507f98cSAndroid Build Coastguard Worker VersionEdit* edit, SequenceNumber* max_sequence) 128*9507f98cSAndroid Build Coastguard Worker EXCLUSIVE_LOCKS_REQUIRED(mutex_); 129*9507f98cSAndroid Build Coastguard Worker 130*9507f98cSAndroid Build Coastguard Worker Status WriteLevel0Table(MemTable* mem, VersionEdit* edit, Version* base) 131*9507f98cSAndroid Build Coastguard Worker EXCLUSIVE_LOCKS_REQUIRED(mutex_); 132*9507f98cSAndroid Build Coastguard Worker 133*9507f98cSAndroid Build Coastguard Worker Status MakeRoomForWrite(bool force /* compact even if there is room? */) 134*9507f98cSAndroid Build Coastguard Worker EXCLUSIVE_LOCKS_REQUIRED(mutex_); 135*9507f98cSAndroid Build Coastguard Worker WriteBatch* BuildBatchGroup(Writer** last_writer) 136*9507f98cSAndroid Build Coastguard Worker EXCLUSIVE_LOCKS_REQUIRED(mutex_); 137*9507f98cSAndroid Build Coastguard Worker 138*9507f98cSAndroid Build Coastguard Worker void RecordBackgroundError(const Status& s); 139*9507f98cSAndroid Build Coastguard Worker 140*9507f98cSAndroid Build Coastguard Worker void MaybeScheduleCompaction() EXCLUSIVE_LOCKS_REQUIRED(mutex_); 141*9507f98cSAndroid Build Coastguard Worker static void BGWork(void* db); 142*9507f98cSAndroid Build Coastguard Worker void BackgroundCall(); 143*9507f98cSAndroid Build Coastguard Worker void BackgroundCompaction() EXCLUSIVE_LOCKS_REQUIRED(mutex_); 144*9507f98cSAndroid Build Coastguard Worker void CleanupCompaction(CompactionState* compact) 145*9507f98cSAndroid Build Coastguard Worker EXCLUSIVE_LOCKS_REQUIRED(mutex_); 146*9507f98cSAndroid Build Coastguard Worker Status DoCompactionWork(CompactionState* compact) 147*9507f98cSAndroid Build Coastguard Worker EXCLUSIVE_LOCKS_REQUIRED(mutex_); 148*9507f98cSAndroid Build Coastguard Worker 149*9507f98cSAndroid Build Coastguard Worker Status OpenCompactionOutputFile(CompactionState* compact); 150*9507f98cSAndroid Build Coastguard Worker Status FinishCompactionOutputFile(CompactionState* compact, Iterator* input); 151*9507f98cSAndroid Build Coastguard Worker Status InstallCompactionResults(CompactionState* compact) 152*9507f98cSAndroid Build Coastguard Worker EXCLUSIVE_LOCKS_REQUIRED(mutex_); 153*9507f98cSAndroid Build Coastguard Worker user_comparator()154*9507f98cSAndroid Build Coastguard Worker const Comparator* user_comparator() const { 155*9507f98cSAndroid Build Coastguard Worker return internal_comparator_.user_comparator(); 156*9507f98cSAndroid Build Coastguard Worker } 157*9507f98cSAndroid Build Coastguard Worker 158*9507f98cSAndroid Build Coastguard Worker // Constant after construction 159*9507f98cSAndroid Build Coastguard Worker Env* const env_; 160*9507f98cSAndroid Build Coastguard Worker const InternalKeyComparator internal_comparator_; 161*9507f98cSAndroid Build Coastguard Worker const InternalFilterPolicy internal_filter_policy_; 162*9507f98cSAndroid Build Coastguard Worker const Options options_; // options_.comparator == &internal_comparator_ 163*9507f98cSAndroid Build Coastguard Worker const bool owns_info_log_; 164*9507f98cSAndroid Build Coastguard Worker const bool owns_cache_; 165*9507f98cSAndroid Build Coastguard Worker const std::string dbname_; 166*9507f98cSAndroid Build Coastguard Worker 167*9507f98cSAndroid Build Coastguard Worker // table_cache_ provides its own synchronization 168*9507f98cSAndroid Build Coastguard Worker TableCache* const table_cache_; 169*9507f98cSAndroid Build Coastguard Worker 170*9507f98cSAndroid Build Coastguard Worker // Lock over the persistent DB state. Non-null iff successfully acquired. 171*9507f98cSAndroid Build Coastguard Worker FileLock* db_lock_; 172*9507f98cSAndroid Build Coastguard Worker 173*9507f98cSAndroid Build Coastguard Worker // State below is protected by mutex_ 174*9507f98cSAndroid Build Coastguard Worker port::Mutex mutex_; 175*9507f98cSAndroid Build Coastguard Worker std::atomic<bool> shutting_down_; 176*9507f98cSAndroid Build Coastguard Worker port::CondVar background_work_finished_signal_ GUARDED_BY(mutex_); 177*9507f98cSAndroid Build Coastguard Worker MemTable* mem_; 178*9507f98cSAndroid Build Coastguard Worker MemTable* imm_ GUARDED_BY(mutex_); // Memtable being compacted 179*9507f98cSAndroid Build Coastguard Worker std::atomic<bool> has_imm_; // So bg thread can detect non-null imm_ 180*9507f98cSAndroid Build Coastguard Worker WritableFile* logfile_; 181*9507f98cSAndroid Build Coastguard Worker uint64_t logfile_number_ GUARDED_BY(mutex_); 182*9507f98cSAndroid Build Coastguard Worker log::Writer* log_; 183*9507f98cSAndroid Build Coastguard Worker uint32_t seed_ GUARDED_BY(mutex_); // For sampling. 184*9507f98cSAndroid Build Coastguard Worker 185*9507f98cSAndroid Build Coastguard Worker // Queue of writers. 186*9507f98cSAndroid Build Coastguard Worker std::deque<Writer*> writers_ GUARDED_BY(mutex_); 187*9507f98cSAndroid Build Coastguard Worker WriteBatch* tmp_batch_ GUARDED_BY(mutex_); 188*9507f98cSAndroid Build Coastguard Worker 189*9507f98cSAndroid Build Coastguard Worker SnapshotList snapshots_ GUARDED_BY(mutex_); 190*9507f98cSAndroid Build Coastguard Worker 191*9507f98cSAndroid Build Coastguard Worker // Set of table files to protect from deletion because they are 192*9507f98cSAndroid Build Coastguard Worker // part of ongoing compactions. 193*9507f98cSAndroid Build Coastguard Worker std::set<uint64_t> pending_outputs_ GUARDED_BY(mutex_); 194*9507f98cSAndroid Build Coastguard Worker 195*9507f98cSAndroid Build Coastguard Worker // Has a background compaction been scheduled or is running? 196*9507f98cSAndroid Build Coastguard Worker bool background_compaction_scheduled_ GUARDED_BY(mutex_); 197*9507f98cSAndroid Build Coastguard Worker 198*9507f98cSAndroid Build Coastguard Worker ManualCompaction* manual_compaction_ GUARDED_BY(mutex_); 199*9507f98cSAndroid Build Coastguard Worker 200*9507f98cSAndroid Build Coastguard Worker VersionSet* const versions_ GUARDED_BY(mutex_); 201*9507f98cSAndroid Build Coastguard Worker 202*9507f98cSAndroid Build Coastguard Worker // Have we encountered a background error in paranoid mode? 203*9507f98cSAndroid Build Coastguard Worker Status bg_error_ GUARDED_BY(mutex_); 204*9507f98cSAndroid Build Coastguard Worker 205*9507f98cSAndroid Build Coastguard Worker CompactionStats stats_[config::kNumLevels] GUARDED_BY(mutex_); 206*9507f98cSAndroid Build Coastguard Worker }; 207*9507f98cSAndroid Build Coastguard Worker 208*9507f98cSAndroid Build Coastguard Worker // Sanitize db options. The caller should delete result.info_log if 209*9507f98cSAndroid Build Coastguard Worker // it is not equal to src.info_log. 210*9507f98cSAndroid Build Coastguard Worker Options SanitizeOptions(const std::string& db, 211*9507f98cSAndroid Build Coastguard Worker const InternalKeyComparator* icmp, 212*9507f98cSAndroid Build Coastguard Worker const InternalFilterPolicy* ipolicy, 213*9507f98cSAndroid Build Coastguard Worker const Options& src); 214*9507f98cSAndroid Build Coastguard Worker 215*9507f98cSAndroid Build Coastguard Worker } // namespace leveldb 216*9507f98cSAndroid Build Coastguard Worker 217*9507f98cSAndroid Build Coastguard Worker #endif // STORAGE_LEVELDB_DB_DB_IMPL_H_ 218