env.h
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 // An Env is an interface used by the leveldb implementation to access 6 // operating system functionality like the filesystem etc. Callers 7 // may wish to provide a custom Env object when opening a database to 8 // get fine gain control; e.g., to rate limit file system operations. 9 // 10 // All Env implementations are safe for concurrent access from 11 // multiple threads without any external synchronization. 12 13 #ifndef STORAGE_LEVELDB_INCLUDE_ENV_H_ 14 #define STORAGE_LEVELDB_INCLUDE_ENV_H_ 15 16 #include <stdarg.h> 17 #include <stdint.h> 18 19 #include <string> 20 #include <vector> 21 22 #include "leveldb/export.h" 23 #include "leveldb/status.h" 24 25 #if defined(_WIN32) 26 // The leveldb::Env class below contains a DeleteFile method. 27 // At the same time, <windows.h>, a fairly popular header 28 // file for Windows applications, defines a DeleteFile macro. 29 // 30 // Without any intervention on our part, the result of this 31 // unfortunate coincidence is that the name of the 32 // leveldb::Env::DeleteFile method seen by the compiler depends on 33 // whether <windows.h> was included before or after the LevelDB 34 // headers. 35 // 36 // To avoid headaches, we undefined DeleteFile (if defined) and 37 // redefine it at the bottom of this file. This way <windows.h> 38 // can be included before this file (or not at all) and the 39 // exported method will always be leveldb::Env::DeleteFile. 40 #if defined(DeleteFile) 41 #undef DeleteFile 42 #define LEVELDB_DELETEFILE_UNDEFINED 43 #endif // defined(DeleteFile) 44 #endif // defined(_WIN32) 45 46 namespace leveldb { 47 48 class FileLock; 49 class Logger; 50 class RandomAccessFile; 51 class SequentialFile; 52 class Slice; 53 class WritableFile; 54 55 class LEVELDB_EXPORT Env { 56 public: 57 Env() = default; 58 59 Env(const Env&) = delete; 60 Env& operator=(const Env&) = delete; 61 62 virtual ~Env(); 63 64 // Return a default environment suitable for the current operating 65 // system. Sophisticated users may wish to provide their own Env 66 // implementation instead of relying on this default environment. 67 // 68 // The result of Default() belongs to leveldb and must never be deleted. 69 static Env* Default(); 70 71 // Create an object that sequentially reads the file with the specified name. 72 // On success, stores a pointer to the new file in *result and returns OK. 73 // On failure stores nullptr in *result and returns non-OK. If the file does 74 // not exist, returns a non-OK status. Implementations should return a 75 // NotFound status when the file does not exist. 76 // 77 // The returned file will only be accessed by one thread at a time. 78 virtual Status NewSequentialFile(const std::string& fname, 79 SequentialFile** result) = 0; 80 81 // Create an object supporting random-access reads from the file with the 82 // specified name. On success, stores a pointer to the new file in 83 // *result and returns OK. On failure stores nullptr in *result and 84 // returns non-OK. If the file does not exist, returns a non-OK 85 // status. Implementations should return a NotFound status when the file does 86 // not exist. 87 // 88 // The returned file may be concurrently accessed by multiple threads. 89 virtual Status NewRandomAccessFile(const std::string& fname, 90 RandomAccessFile** result) = 0; 91 92 // Create an object that writes to a new file with the specified 93 // name. Deletes any existing file with the same name and creates a 94 // new file. On success, stores a pointer to the new file in 95 // *result and returns OK. On failure stores nullptr in *result and 96 // returns non-OK. 97 // 98 // The returned file will only be accessed by one thread at a time. 99 virtual Status NewWritableFile(const std::string& fname, 100 WritableFile** result) = 0; 101 102 // Create an object that either appends to an existing file, or 103 // writes to a new file (if the file does not exist to begin with). 104 // On success, stores a pointer to the new file in *result and 105 // returns OK. On failure stores nullptr in *result and returns 106 // non-OK. 107 // 108 // The returned file will only be accessed by one thread at a time. 109 // 110 // May return an IsNotSupportedError error if this Env does 111 // not allow appending to an existing file. Users of Env (including 112 // the leveldb implementation) must be prepared to deal with 113 // an Env that does not support appending. 114 virtual Status NewAppendableFile(const std::string& fname, 115 WritableFile** result); 116 117 // Returns true iff the named file exists. 118 virtual bool FileExists(const std::string& fname) = 0; 119 120 // Store in *result the names of the children of the specified directory. 121 // The names are relative to "dir". 122 // Original contents of *results are dropped. 123 virtual Status GetChildren(const std::string& dir, 124 std::vector<std::string>* result) = 0; 125 126 // Delete the named file. 127 virtual Status DeleteFile(const std::string& fname) = 0; 128 129 // Create the specified directory. 130 virtual Status CreateDir(const std::string& dirname) = 0; 131 132 // Delete the specified directory. 133 virtual Status DeleteDir(const std::string& dirname) = 0; 134 135 // Store the size of fname in *file_size. 136 virtual Status GetFileSize(const std::string& fname, uint64_t* file_size) = 0; 137 138 // Rename file src to target. 139 virtual Status RenameFile(const std::string& src, 140 const std::string& target) = 0; 141 142 // Lock the specified file. Used to prevent concurrent access to 143 // the same db by multiple processes. On failure, stores nullptr in 144 // *lock and returns non-OK. 145 // 146 // On success, stores a pointer to the object that represents the 147 // acquired lock in *lock and returns OK. The caller should call 148 // UnlockFile(*lock) to release the lock. If the process exits, 149 // the lock will be automatically released. 150 // 151 // If somebody else already holds the lock, finishes immediately 152 // with a failure. I.e., this call does not wait for existing locks 153 // to go away. 154 // 155 // May create the named file if it does not already exist. 156 virtual Status LockFile(const std::string& fname, FileLock** lock) = 0; 157 158 // Release the lock acquired by a previous successful call to LockFile. 159 // REQUIRES: lock was returned by a successful LockFile() call 160 // REQUIRES: lock has not already been unlocked. 161 virtual Status UnlockFile(FileLock* lock) = 0; 162 163 // Arrange to run "(*function)(arg)" once in a background thread. 164 // 165 // "function" may run in an unspecified thread. Multiple functions 166 // added to the same Env may run concurrently in different threads. 167 // I.e., the caller may not assume that background work items are 168 // serialized. 169 virtual void Schedule(void (*function)(void* arg), void* arg) = 0; 170 171 // Start a new thread, invoking "function(arg)" within the new thread. 172 // When "function(arg)" returns, the thread will be destroyed. 173 virtual void StartThread(void (*function)(void* arg), void* arg) = 0; 174 175 // *path is set to a temporary directory that can be used for testing. It may 176 // or may not have just been created. The directory may or may not differ 177 // between runs of the same process, but subsequent calls will return the 178 // same directory. 179 virtual Status GetTestDirectory(std::string* path) = 0; 180 181 // Create and return a log file for storing informational messages. 182 virtual Status NewLogger(const std::string& fname, Logger** result) = 0; 183 184 // Returns the number of micro-seconds since some fixed point in time. Only 185 // useful for computing deltas of time. 186 virtual uint64_t NowMicros() = 0; 187 188 // Sleep/delay the thread for the prescribed number of micro-seconds. 189 virtual void SleepForMicroseconds(int micros) = 0; 190 }; 191 192 // A file abstraction for reading sequentially through a file 193 class LEVELDB_EXPORT SequentialFile { 194 public: 195 SequentialFile() = default; 196 197 SequentialFile(const SequentialFile&) = delete; 198 SequentialFile& operator=(const SequentialFile&) = delete; 199 200 virtual ~SequentialFile(); 201 202 // Read up to "n" bytes from the file. "scratch[0..n-1]" may be 203 // written by this routine. Sets "*result" to the data that was 204 // read (including if fewer than "n" bytes were successfully read). 205 // May set "*result" to point at data in "scratch[0..n-1]", so 206 // "scratch[0..n-1]" must be live when "*result" is used. 207 // If an error was encountered, returns a non-OK status. 208 // 209 // REQUIRES: External synchronization 210 virtual Status Read(size_t n, Slice* result, char* scratch) = 0; 211 212 // Skip "n" bytes from the file. This is guaranteed to be no 213 // slower that reading the same data, but may be faster. 214 // 215 // If end of file is reached, skipping will stop at the end of the 216 // file, and Skip will return OK. 217 // 218 // REQUIRES: External synchronization 219 virtual Status Skip(uint64_t n) = 0; 220 221 // Get a name for the file, only for error reporting 222 virtual std::string GetName() const = 0; 223 }; 224 225 // A file abstraction for randomly reading the contents of a file. 226 class LEVELDB_EXPORT RandomAccessFile { 227 public: 228 RandomAccessFile() = default; 229 230 RandomAccessFile(const RandomAccessFile&) = delete; 231 RandomAccessFile& operator=(const RandomAccessFile&) = delete; 232 233 virtual ~RandomAccessFile(); 234 235 // Read up to "n" bytes from the file starting at "offset". 236 // "scratch[0..n-1]" may be written by this routine. Sets "*result" 237 // to the data that was read (including if fewer than "n" bytes were 238 // successfully read). May set "*result" to point at data in 239 // "scratch[0..n-1]", so "scratch[0..n-1]" must be live when 240 // "*result" is used. If an error was encountered, returns a non-OK 241 // status. 242 // 243 // Safe for concurrent use by multiple threads. 244 virtual Status Read(uint64_t offset, size_t n, Slice* result, 245 char* scratch) const = 0; 246 247 // Get a name for the file, only for error reporting 248 virtual std::string GetName() const = 0; 249 }; 250 251 // A file abstraction for sequential writing. The implementation 252 // must provide buffering since callers may append small fragments 253 // at a time to the file. 254 class LEVELDB_EXPORT WritableFile { 255 public: 256 WritableFile() = default; 257 258 WritableFile(const WritableFile&) = delete; 259 WritableFile& operator=(const WritableFile&) = delete; 260 261 virtual ~WritableFile(); 262 263 virtual Status Append(const Slice& data) = 0; 264 virtual Status Close() = 0; 265 virtual Status Flush() = 0; 266 virtual Status Sync() = 0; 267 268 // Get a name for the file, only for error reporting 269 virtual std::string GetName() const = 0; 270 }; 271 272 // An interface for writing log messages. 273 class LEVELDB_EXPORT Logger { 274 public: 275 Logger() = default; 276 277 Logger(const Logger&) = delete; 278 Logger& operator=(const Logger&) = delete; 279 280 virtual ~Logger(); 281 282 // Write an entry to the log file with the specified format. 283 virtual void Logv(const char* format, va_list ap) = 0; 284 }; 285 286 // Identifies a locked file. 287 class LEVELDB_EXPORT FileLock { 288 public: 289 FileLock() = default; 290 291 FileLock(const FileLock&) = delete; 292 FileLock& operator=(const FileLock&) = delete; 293 294 virtual ~FileLock(); 295 }; 296 297 // Log the specified data to *info_log if info_log is non-null. 298 void Log(Logger* info_log, const char* format, ...) 299 #if defined(__GNUC__) || defined(__clang__) 300 __attribute__((__format__(__printf__, 2, 3))) 301 #endif 302 ; 303 304 // A utility routine: write "data" to the named file. 305 LEVELDB_EXPORT Status WriteStringToFile(Env* env, const Slice& data, 306 const std::string& fname); 307 308 // A utility routine: read contents of named file into *data 309 LEVELDB_EXPORT Status ReadFileToString(Env* env, const std::string& fname, 310 std::string* data); 311 312 // An implementation of Env that forwards all calls to another Env. 313 // May be useful to clients who wish to override just part of the 314 // functionality of another Env. 315 class LEVELDB_EXPORT EnvWrapper : public Env { 316 public: 317 // Initialize an EnvWrapper that delegates all calls to *t. 318 explicit EnvWrapper(Env* t) : target_(t) {} 319 virtual ~EnvWrapper(); 320 321 // Return the target to which this Env forwards all calls. 322 Env* target() const { return target_; } 323 324 // The following text is boilerplate that forwards all methods to target(). 325 Status NewSequentialFile(const std::string& f, SequentialFile** r) override { 326 return target_->NewSequentialFile(f, r); 327 } 328 Status NewRandomAccessFile(const std::string& f, 329 RandomAccessFile** r) override { 330 return target_->NewRandomAccessFile(f, r); 331 } 332 Status NewWritableFile(const std::string& f, WritableFile** r) override { 333 return target_->NewWritableFile(f, r); 334 } 335 Status NewAppendableFile(const std::string& f, WritableFile** r) override { 336 return target_->NewAppendableFile(f, r); 337 } 338 bool FileExists(const std::string& f) override { 339 return target_->FileExists(f); 340 } 341 Status GetChildren(const std::string& dir, 342 std::vector<std::string>* r) override { 343 return target_->GetChildren(dir, r); 344 } 345 Status DeleteFile(const std::string& f) override { 346 return target_->DeleteFile(f); 347 } 348 Status CreateDir(const std::string& d) override { 349 return target_->CreateDir(d); 350 } 351 Status DeleteDir(const std::string& d) override { 352 return target_->DeleteDir(d); 353 } 354 Status GetFileSize(const std::string& f, uint64_t* s) override { 355 return target_->GetFileSize(f, s); 356 } 357 Status RenameFile(const std::string& s, const std::string& t) override { 358 return target_->RenameFile(s, t); 359 } 360 Status LockFile(const std::string& f, FileLock** l) override { 361 return target_->LockFile(f, l); 362 } 363 Status UnlockFile(FileLock* l) override { return target_->UnlockFile(l); } 364 void Schedule(void (*f)(void*), void* a) override { 365 return target_->Schedule(f, a); 366 } 367 void StartThread(void (*f)(void*), void* a) override { 368 return target_->StartThread(f, a); 369 } 370 Status GetTestDirectory(std::string* path) override { 371 return target_->GetTestDirectory(path); 372 } 373 Status NewLogger(const std::string& fname, Logger** result) override { 374 return target_->NewLogger(fname, result); 375 } 376 uint64_t NowMicros() override { return target_->NowMicros(); } 377 void SleepForMicroseconds(int micros) override { 378 target_->SleepForMicroseconds(micros); 379 } 380 381 private: 382 Env* target_; 383 }; 384 385 } // namespace leveldb 386 387 // Redefine DeleteFile if necessary. 388 #if defined(_WIN32) && defined(LEVELDB_DELETEFILE_UNDEFINED) 389 #if defined(UNICODE) 390 #define DeleteFile DeleteFileW 391 #else 392 #define DeleteFile DeleteFileA 393 #endif // defined(UNICODE) 394 #endif // defined(_WIN32) && defined(LEVELDB_DELETEFILE_UNDEFINED) 395 396 #endif // STORAGE_LEVELDB_INCLUDE_ENV_H_