/ src / leveldb / include / leveldb / env.h
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_