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