1 // Copyright (c) 2019-present, Facebook, Inc. All rights reserved. 2 // This source code is licensed under both the GPLv2 (found in the 3 // COPYING file in the root directory) and Apache 2.0 License 4 // (found in the LICENSE.Apache file in the root directory). 5 6 #pragma once 7 8 #include "rocksdb/env.h" 9 #include "rocksdb/file_system.h" 10 #include "rocksdb/system_clock.h" 11 12 #ifdef _WIN32 13 // Windows API macro interference 14 #undef DeleteFile 15 #undef GetCurrentTime 16 #undef LoadLibrary 17 #endif 18 19 namespace ROCKSDB_NAMESPACE { 20 21 class CompositeEnv : public Env { 22 public: 23 // Initialize a CompositeEnvWrapper that delegates all thread/time related 24 // calls to env, and all file operations to fs CompositeEnv(const std::shared_ptr<FileSystem> & fs,const std::shared_ptr<SystemClock> & clock)25 explicit CompositeEnv(const std::shared_ptr<FileSystem>& fs, 26 const std::shared_ptr<SystemClock>& clock) 27 : Env(fs, clock) {} 28 RegisterDbPaths(const std::vector<std::string> & paths)29 Status RegisterDbPaths(const std::vector<std::string>& paths) override { 30 return file_system_->RegisterDbPaths(paths); 31 } UnregisterDbPaths(const std::vector<std::string> & paths)32 Status UnregisterDbPaths(const std::vector<std::string>& paths) override { 33 return file_system_->UnregisterDbPaths(paths); 34 } 35 36 // The following text is boilerplate that forwards all methods to target() 37 Status NewSequentialFile(const std::string& f, 38 std::unique_ptr<SequentialFile>* r, 39 const EnvOptions& options) override; 40 41 Status NewRandomAccessFile(const std::string& f, 42 std::unique_ptr<RandomAccessFile>* r, 43 const EnvOptions& options) override; 44 45 Status NewWritableFile(const std::string& f, std::unique_ptr<WritableFile>* r, 46 const EnvOptions& options) override; 47 48 Status ReopenWritableFile(const std::string& fname, 49 std::unique_ptr<WritableFile>* result, 50 const EnvOptions& options) override; 51 52 Status ReuseWritableFile(const std::string& fname, 53 const std::string& old_fname, 54 std::unique_ptr<WritableFile>* r, 55 const EnvOptions& options) override; 56 57 Status NewRandomRWFile(const std::string& fname, 58 std::unique_ptr<RandomRWFile>* result, 59 const EnvOptions& options) override; 60 NewMemoryMappedFileBuffer(const std::string & fname,std::unique_ptr<MemoryMappedFileBuffer> * result)61 Status NewMemoryMappedFileBuffer( 62 const std::string& fname, 63 std::unique_ptr<MemoryMappedFileBuffer>* result) override { 64 return file_system_->NewMemoryMappedFileBuffer(fname, result); 65 } 66 67 Status NewDirectory(const std::string& name, 68 std::unique_ptr<Directory>* result) override; 69 FileExists(const std::string & f)70 Status FileExists(const std::string& f) override { 71 IOOptions io_opts; 72 IODebugContext dbg; 73 return file_system_->FileExists(f, io_opts, &dbg); 74 } GetChildren(const std::string & dir,std::vector<std::string> * r)75 Status GetChildren(const std::string& dir, 76 std::vector<std::string>* r) override { 77 IOOptions io_opts; 78 IODebugContext dbg; 79 return file_system_->GetChildren(dir, io_opts, r, &dbg); 80 } GetChildrenFileAttributes(const std::string & dir,std::vector<FileAttributes> * result)81 Status GetChildrenFileAttributes( 82 const std::string& dir, std::vector<FileAttributes>* result) override { 83 IOOptions io_opts; 84 IODebugContext dbg; 85 return file_system_->GetChildrenFileAttributes(dir, io_opts, result, &dbg); 86 } DeleteFile(const std::string & f)87 Status DeleteFile(const std::string& f) override { 88 IOOptions io_opts; 89 IODebugContext dbg; 90 return file_system_->DeleteFile(f, io_opts, &dbg); 91 } Truncate(const std::string & fname,size_t size)92 Status Truncate(const std::string& fname, size_t size) override { 93 IOOptions io_opts; 94 IODebugContext dbg; 95 return file_system_->Truncate(fname, size, io_opts, &dbg); 96 } CreateDir(const std::string & d)97 Status CreateDir(const std::string& d) override { 98 IOOptions io_opts; 99 IODebugContext dbg; 100 return file_system_->CreateDir(d, io_opts, &dbg); 101 } CreateDirIfMissing(const std::string & d)102 Status CreateDirIfMissing(const std::string& d) override { 103 IOOptions io_opts; 104 IODebugContext dbg; 105 return file_system_->CreateDirIfMissing(d, io_opts, &dbg); 106 } DeleteDir(const std::string & d)107 Status DeleteDir(const std::string& d) override { 108 IOOptions io_opts; 109 IODebugContext dbg; 110 return file_system_->DeleteDir(d, io_opts, &dbg); 111 } GetFileSize(const std::string & f,uint64_t * s)112 Status GetFileSize(const std::string& f, uint64_t* s) override { 113 IOOptions io_opts; 114 IODebugContext dbg; 115 return file_system_->GetFileSize(f, io_opts, s, &dbg); 116 } 117 GetFileModificationTime(const std::string & fname,uint64_t * file_mtime)118 Status GetFileModificationTime(const std::string& fname, 119 uint64_t* file_mtime) override { 120 IOOptions io_opts; 121 IODebugContext dbg; 122 return file_system_->GetFileModificationTime(fname, io_opts, file_mtime, 123 &dbg); 124 } 125 RenameFile(const std::string & s,const std::string & t)126 Status RenameFile(const std::string& s, const std::string& t) override { 127 IOOptions io_opts; 128 IODebugContext dbg; 129 return file_system_->RenameFile(s, t, io_opts, &dbg); 130 } 131 LinkFile(const std::string & s,const std::string & t)132 Status LinkFile(const std::string& s, const std::string& t) override { 133 IOOptions io_opts; 134 IODebugContext dbg; 135 return file_system_->LinkFile(s, t, io_opts, &dbg); 136 } 137 NumFileLinks(const std::string & fname,uint64_t * count)138 Status NumFileLinks(const std::string& fname, uint64_t* count) override { 139 IOOptions io_opts; 140 IODebugContext dbg; 141 return file_system_->NumFileLinks(fname, io_opts, count, &dbg); 142 } 143 AreFilesSame(const std::string & first,const std::string & second,bool * res)144 Status AreFilesSame(const std::string& first, const std::string& second, 145 bool* res) override { 146 IOOptions io_opts; 147 IODebugContext dbg; 148 return file_system_->AreFilesSame(first, second, io_opts, res, &dbg); 149 } 150 LockFile(const std::string & f,FileLock ** l)151 Status LockFile(const std::string& f, FileLock** l) override { 152 IOOptions io_opts; 153 IODebugContext dbg; 154 return file_system_->LockFile(f, io_opts, l, &dbg); 155 } 156 UnlockFile(FileLock * l)157 Status UnlockFile(FileLock* l) override { 158 IOOptions io_opts; 159 IODebugContext dbg; 160 return file_system_->UnlockFile(l, io_opts, &dbg); 161 } 162 GetAbsolutePath(const std::string & db_path,std::string * output_path)163 Status GetAbsolutePath(const std::string& db_path, 164 std::string* output_path) override { 165 IOOptions io_opts; 166 IODebugContext dbg; 167 return file_system_->GetAbsolutePath(db_path, io_opts, output_path, &dbg); 168 } 169 NewLogger(const std::string & fname,std::shared_ptr<Logger> * result)170 Status NewLogger(const std::string& fname, 171 std::shared_ptr<Logger>* result) override { 172 IOOptions io_opts; 173 IODebugContext dbg; 174 return file_system_->NewLogger(fname, io_opts, result, &dbg); 175 } 176 IsDirectory(const std::string & path,bool * is_dir)177 Status IsDirectory(const std::string& path, bool* is_dir) override { 178 IOOptions io_opts; 179 IODebugContext dbg; 180 return file_system_->IsDirectory(path, io_opts, is_dir, &dbg); 181 } 182 GetTestDirectory(std::string * path)183 Status GetTestDirectory(std::string* path) override { 184 IOOptions io_opts; 185 IODebugContext dbg; 186 return file_system_->GetTestDirectory(io_opts, path, &dbg); 187 } 188 OptimizeForLogRead(const EnvOptions & env_options)189 EnvOptions OptimizeForLogRead(const EnvOptions& env_options) const override { 190 return file_system_->OptimizeForLogRead(FileOptions(env_options)); 191 } 192 OptimizeForManifestRead(const EnvOptions & env_options)193 EnvOptions OptimizeForManifestRead( 194 const EnvOptions& env_options) const override { 195 return file_system_->OptimizeForManifestRead(FileOptions(env_options)); 196 } 197 OptimizeForLogWrite(const EnvOptions & env_options,const DBOptions & db_options)198 EnvOptions OptimizeForLogWrite(const EnvOptions& env_options, 199 const DBOptions& db_options) const override { 200 return file_system_->OptimizeForLogWrite(FileOptions(env_options), 201 db_options); 202 } 203 OptimizeForManifestWrite(const EnvOptions & env_options)204 EnvOptions OptimizeForManifestWrite( 205 const EnvOptions& env_options) const override { 206 return file_system_->OptimizeForManifestWrite(FileOptions(env_options)); 207 } 208 OptimizeForCompactionTableWrite(const EnvOptions & env_options,const ImmutableDBOptions & immutable_ops)209 EnvOptions OptimizeForCompactionTableWrite( 210 const EnvOptions& env_options, 211 const ImmutableDBOptions& immutable_ops) const override { 212 return file_system_->OptimizeForCompactionTableWrite( 213 FileOptions(env_options), immutable_ops); 214 } OptimizeForCompactionTableRead(const EnvOptions & env_options,const ImmutableDBOptions & db_options)215 EnvOptions OptimizeForCompactionTableRead( 216 const EnvOptions& env_options, 217 const ImmutableDBOptions& db_options) const override { 218 return file_system_->OptimizeForCompactionTableRead( 219 FileOptions(env_options), db_options); 220 } OptimizeForBlobFileRead(const EnvOptions & env_options,const ImmutableDBOptions & db_options)221 EnvOptions OptimizeForBlobFileRead( 222 const EnvOptions& env_options, 223 const ImmutableDBOptions& db_options) const override { 224 return file_system_->OptimizeForBlobFileRead(FileOptions(env_options), 225 db_options); 226 } 227 // This seems to clash with a macro on Windows, so #undef it here 228 #ifdef GetFreeSpace 229 #undef GetFreeSpace 230 #endif GetFreeSpace(const std::string & path,uint64_t * diskfree)231 Status GetFreeSpace(const std::string& path, uint64_t* diskfree) override { 232 IOOptions io_opts; 233 IODebugContext dbg; 234 return file_system_->GetFreeSpace(path, io_opts, diskfree, &dbg); 235 } NowMicros()236 uint64_t NowMicros() override { return system_clock_->NowMicros(); } NowNanos()237 uint64_t NowNanos() override { return system_clock_->NowNanos(); } 238 NowCPUNanos()239 uint64_t NowCPUNanos() override { return system_clock_->CPUNanos(); } 240 SleepForMicroseconds(int micros)241 void SleepForMicroseconds(int micros) override { 242 system_clock_->SleepForMicroseconds(micros); 243 } 244 GetCurrentTime(int64_t * unix_time)245 Status GetCurrentTime(int64_t* unix_time) override { 246 return system_clock_->GetCurrentTime(unix_time); 247 } TimeToString(uint64_t time)248 std::string TimeToString(uint64_t time) override { 249 return system_clock_->TimeToString(time); 250 } 251 }; 252 253 class CompositeEnvWrapper : public CompositeEnv { 254 public: 255 // Initialize a CompositeEnvWrapper that delegates all thread/time related 256 // calls to env, and all file operations to fs CompositeEnvWrapper(Env * env,const std::shared_ptr<FileSystem> & fs)257 explicit CompositeEnvWrapper(Env* env, const std::shared_ptr<FileSystem>& fs) 258 : CompositeEnvWrapper(env, fs, env->GetSystemClock()) {} 259 CompositeEnvWrapper(Env * env,const std::shared_ptr<SystemClock> & sc)260 explicit CompositeEnvWrapper(Env* env, const std::shared_ptr<SystemClock>& sc) 261 : CompositeEnvWrapper(env, env->GetFileSystem(), sc) {} 262 CompositeEnvWrapper(Env * env,const std::shared_ptr<FileSystem> & fs,const std::shared_ptr<SystemClock> & sc)263 explicit CompositeEnvWrapper(Env* env, const std::shared_ptr<FileSystem>& fs, 264 const std::shared_ptr<SystemClock>& sc) 265 : CompositeEnv(fs, sc), env_target_(env) {} 266 267 // Return the target to which this Env forwards all calls env_target()268 Env* env_target() const { return env_target_; } 269 270 #if !defined(OS_WIN) && !defined(ROCKSDB_NO_DYNAMIC_EXTENSION) LoadLibrary(const std::string & lib_name,const std::string & search_path,std::shared_ptr<DynamicLibrary> * result)271 Status LoadLibrary(const std::string& lib_name, 272 const std::string& search_path, 273 std::shared_ptr<DynamicLibrary>* result) override { 274 return env_target_->LoadLibrary(lib_name, search_path, result); 275 } 276 #endif 277 278 void Schedule(void (*f)(void* arg), void* a, Priority pri, 279 void* tag = nullptr, void (*u)(void* arg) = nullptr) override { 280 return env_target_->Schedule(f, a, pri, tag, u); 281 } 282 UnSchedule(void * tag,Priority pri)283 int UnSchedule(void* tag, Priority pri) override { 284 return env_target_->UnSchedule(tag, pri); 285 } 286 StartThread(void (* f)(void *),void * a)287 void StartThread(void (*f)(void*), void* a) override { 288 return env_target_->StartThread(f, a); 289 } WaitForJoin()290 void WaitForJoin() override { return env_target_->WaitForJoin(); } 291 unsigned int GetThreadPoolQueueLen(Priority pri = LOW) const override { 292 return env_target_->GetThreadPoolQueueLen(pri); 293 } 294 GetHostName(char * name,uint64_t len)295 Status GetHostName(char* name, uint64_t len) override { 296 return env_target_->GetHostName(name, len); 297 } SetBackgroundThreads(int num,Priority pri)298 void SetBackgroundThreads(int num, Priority pri) override { 299 return env_target_->SetBackgroundThreads(num, pri); 300 } GetBackgroundThreads(Priority pri)301 int GetBackgroundThreads(Priority pri) override { 302 return env_target_->GetBackgroundThreads(pri); 303 } 304 SetAllowNonOwnerAccess(bool allow_non_owner_access)305 Status SetAllowNonOwnerAccess(bool allow_non_owner_access) override { 306 return env_target_->SetAllowNonOwnerAccess(allow_non_owner_access); 307 } 308 IncBackgroundThreadsIfNeeded(int num,Priority pri)309 void IncBackgroundThreadsIfNeeded(int num, Priority pri) override { 310 return env_target_->IncBackgroundThreadsIfNeeded(num, pri); 311 } 312 LowerThreadPoolIOPriority(Priority pool)313 void LowerThreadPoolIOPriority(Priority pool) override { 314 env_target_->LowerThreadPoolIOPriority(pool); 315 } 316 LowerThreadPoolCPUPriority(Priority pool)317 void LowerThreadPoolCPUPriority(Priority pool) override { 318 env_target_->LowerThreadPoolCPUPriority(pool); 319 } 320 LowerThreadPoolCPUPriority(Priority pool,CpuPriority pri)321 Status LowerThreadPoolCPUPriority(Priority pool, CpuPriority pri) override { 322 return env_target_->LowerThreadPoolCPUPriority(pool, pri); 323 } 324 GetThreadList(std::vector<ThreadStatus> * thread_list)325 Status GetThreadList(std::vector<ThreadStatus>* thread_list) override { 326 return env_target_->GetThreadList(thread_list); 327 } 328 GetThreadStatusUpdater()329 ThreadStatusUpdater* GetThreadStatusUpdater() const override { 330 return env_target_->GetThreadStatusUpdater(); 331 } 332 GetThreadID()333 uint64_t GetThreadID() const override { return env_target_->GetThreadID(); } 334 GenerateUniqueId()335 std::string GenerateUniqueId() override { 336 return env_target_->GenerateUniqueId(); 337 } 338 339 private: 340 Env* env_target_; 341 }; 342 } // namespace ROCKSDB_NAMESPACE 343