Home | History | Annotate | Download | only in leveldb
      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 <cstdarg>
     17 #include <string>
     18 #include <vector>
     19 #include <stdint.h>
     20 #include "leveldb/status.h"
     21 
     22 namespace leveldb {
     23 
     24 class FileLock;
     25 class Logger;
     26 class RandomAccessFile;
     27 class SequentialFile;
     28 class Slice;
     29 class WritableFile;
     30 
     31 class Env {
     32  public:
     33   Env() { }
     34   virtual ~Env();
     35 
     36   // Return a default environment suitable for the current operating
     37   // system.  Sophisticated users may wish to provide their own Env
     38   // implementation instead of relying on this default environment.
     39   //
     40   // The result of Default() belongs to leveldb and must never be deleted.
     41   static Env* Default();
     42 
     43   // Create a brand new sequentially-readable file with the specified name.
     44   // On success, stores a pointer to the new file in *result and returns OK.
     45   // On failure stores NULL in *result and returns non-OK.  If the file does
     46   // not exist, returns a non-OK status.
     47   //
     48   // The returned file will only be accessed by one thread at a time.
     49   virtual Status NewSequentialFile(const std::string& fname,
     50                                    SequentialFile** result) = 0;
     51 
     52   // Create a brand new random access read-only file with the
     53   // specified name.  On success, stores a pointer to the new file in
     54   // *result and returns OK.  On failure stores NULL in *result and
     55   // returns non-OK.  If the file does not exist, returns a non-OK
     56   // status.
     57   //
     58   // The returned file may be concurrently accessed by multiple threads.
     59   virtual Status NewRandomAccessFile(const std::string& fname,
     60                                      RandomAccessFile** result) = 0;
     61 
     62   // Create an object that writes to a new file with the specified
     63   // name.  Deletes any existing file with the same name and creates a
     64   // new file.  On success, stores a pointer to the new file in
     65   // *result and returns OK.  On failure stores NULL in *result and
     66   // returns non-OK.
     67   //
     68   // The returned file will only be accessed by one thread at a time.
     69   virtual Status NewWritableFile(const std::string& fname,
     70                                  WritableFile** result) = 0;
     71 
     72   // Returns true iff the named file exists.
     73   virtual bool FileExists(const std::string& fname) = 0;
     74 
     75   // Store in *result the names of the children of the specified directory.
     76   // The names are relative to "dir".
     77   // Original contents of *results are dropped.
     78   virtual Status GetChildren(const std::string& dir,
     79                              std::vector<std::string>* result) = 0;
     80 
     81   // Delete the named file.
     82   virtual Status DeleteFile(const std::string& fname) = 0;
     83 
     84   // Create the specified directory.
     85   virtual Status CreateDir(const std::string& dirname) = 0;
     86 
     87   // Delete the specified directory.
     88   virtual Status DeleteDir(const std::string& dirname) = 0;
     89 
     90   // Store the size of fname in *file_size.
     91   virtual Status GetFileSize(const std::string& fname, uint64_t* file_size) = 0;
     92 
     93   // Rename file src to target.
     94   virtual Status RenameFile(const std::string& src,
     95                             const std::string& target) = 0;
     96 
     97   // Lock the specified file.  Used to prevent concurrent access to
     98   // the same db by multiple processes.  On failure, stores NULL in
     99   // *lock and returns non-OK.
    100   //
    101   // On success, stores a pointer to the object that represents the
    102   // acquired lock in *lock and returns OK.  The caller should call
    103   // UnlockFile(*lock) to release the lock.  If the process exits,
    104   // the lock will be automatically released.
    105   //
    106   // If somebody else already holds the lock, finishes immediately
    107   // with a failure.  I.e., this call does not wait for existing locks
    108   // to go away.
    109   //
    110   // May create the named file if it does not already exist.
    111   virtual Status LockFile(const std::string& fname, FileLock** lock) = 0;
    112 
    113   // Release the lock acquired by a previous successful call to LockFile.
    114   // REQUIRES: lock was returned by a successful LockFile() call
    115   // REQUIRES: lock has not already been unlocked.
    116   virtual Status UnlockFile(FileLock* lock) = 0;
    117 
    118   // Arrange to run "(*function)(arg)" once in a background thread.
    119   //
    120   // "function" may run in an unspecified thread.  Multiple functions
    121   // added to the same Env may run concurrently in different threads.
    122   // I.e., the caller may not assume that background work items are
    123   // serialized.
    124   virtual void Schedule(
    125       void (*function)(void* arg),
    126       void* arg) = 0;
    127 
    128   // Start a new thread, invoking "function(arg)" within the new thread.
    129   // When "function(arg)" returns, the thread will be destroyed.
    130   virtual void StartThread(void (*function)(void* arg), void* arg) = 0;
    131 
    132   // *path is set to a temporary directory that can be used for testing. It may
    133   // or many not have just been created. The directory may or may not differ
    134   // between runs of the same process, but subsequent calls will return the
    135   // same directory.
    136   virtual Status GetTestDirectory(std::string* path) = 0;
    137 
    138   // Create and return a log file for storing informational messages.
    139   virtual Status NewLogger(const std::string& fname, Logger** result) = 0;
    140 
    141   // Returns the number of micro-seconds since some fixed point in time. Only
    142   // useful for computing deltas of time.
    143   virtual uint64_t NowMicros() = 0;
    144 
    145   // Sleep/delay the thread for the perscribed number of micro-seconds.
    146   virtual void SleepForMicroseconds(int micros) = 0;
    147 
    148  private:
    149   // No copying allowed
    150   Env(const Env&);
    151   void operator=(const Env&);
    152 };
    153 
    154 // A file abstraction for reading sequentially through a file
    155 class SequentialFile {
    156  public:
    157   SequentialFile() { }
    158   virtual ~SequentialFile();
    159 
    160   // Read up to "n" bytes from the file.  "scratch[0..n-1]" may be
    161   // written by this routine.  Sets "*result" to the data that was
    162   // read (including if fewer than "n" bytes were successfully read).
    163   // May set "*result" to point at data in "scratch[0..n-1]", so
    164   // "scratch[0..n-1]" must be live when "*result" is used.
    165   // If an error was encountered, returns a non-OK status.
    166   //
    167   // REQUIRES: External synchronization
    168   virtual Status Read(size_t n, Slice* result, char* scratch) = 0;
    169 
    170   // Skip "n" bytes from the file. This is guaranteed to be no
    171   // slower that reading the same data, but may be faster.
    172   //
    173   // If end of file is reached, skipping will stop at the end of the
    174   // file, and Skip will return OK.
    175   //
    176   // REQUIRES: External synchronization
    177   virtual Status Skip(uint64_t n) = 0;
    178 
    179  private:
    180   // No copying allowed
    181   SequentialFile(const SequentialFile&);
    182   void operator=(const SequentialFile&);
    183 };
    184 
    185 // A file abstraction for randomly reading the contents of a file.
    186 class RandomAccessFile {
    187  public:
    188   RandomAccessFile() { }
    189   virtual ~RandomAccessFile();
    190 
    191   // Read up to "n" bytes from the file starting at "offset".
    192   // "scratch[0..n-1]" may be written by this routine.  Sets "*result"
    193   // to the data that was read (including if fewer than "n" bytes were
    194   // successfully read).  May set "*result" to point at data in
    195   // "scratch[0..n-1]", so "scratch[0..n-1]" must be live when
    196   // "*result" is used.  If an error was encountered, returns a non-OK
    197   // status.
    198   //
    199   // Safe for concurrent use by multiple threads.
    200   virtual Status Read(uint64_t offset, size_t n, Slice* result,
    201                       char* scratch) const = 0;
    202 
    203  private:
    204   // No copying allowed
    205   RandomAccessFile(const RandomAccessFile&);
    206   void operator=(const RandomAccessFile&);
    207 };
    208 
    209 // A file abstraction for sequential writing.  The implementation
    210 // must provide buffering since callers may append small fragments
    211 // at a time to the file.
    212 class WritableFile {
    213  public:
    214   WritableFile() { }
    215   virtual ~WritableFile();
    216 
    217   virtual Status Append(const Slice& data) = 0;
    218   virtual Status Close() = 0;
    219   virtual Status Flush() = 0;
    220   virtual Status Sync() = 0;
    221 
    222  private:
    223   // No copying allowed
    224   WritableFile(const WritableFile&);
    225   void operator=(const WritableFile&);
    226 };
    227 
    228 // An interface for writing log messages.
    229 class Logger {
    230  public:
    231   Logger() { }
    232   virtual ~Logger();
    233 
    234   // Write an entry to the log file with the specified format.
    235   virtual void Logv(const char* format, va_list ap) = 0;
    236 
    237  private:
    238   // No copying allowed
    239   Logger(const Logger&);
    240   void operator=(const Logger&);
    241 };
    242 
    243 
    244 // Identifies a locked file.
    245 class FileLock {
    246  public:
    247   FileLock() { }
    248   virtual ~FileLock();
    249  private:
    250   // No copying allowed
    251   FileLock(const FileLock&);
    252   void operator=(const FileLock&);
    253 };
    254 
    255 // Log the specified data to *info_log if info_log is non-NULL.
    256 extern void Log(Logger* info_log, const char* format, ...)
    257 #   if defined(__GNUC__) || defined(__clang__)
    258     __attribute__((__format__ (__printf__, 2, 3)))
    259 #   endif
    260     ;
    261 
    262 // A utility routine: write "data" to the named file.
    263 extern Status WriteStringToFile(Env* env, const Slice& data,
    264                                 const std::string& fname);
    265 
    266 // A utility routine: read contents of named file into *data
    267 extern Status ReadFileToString(Env* env, const std::string& fname,
    268                                std::string* data);
    269 
    270 // An implementation of Env that forwards all calls to another Env.
    271 // May be useful to clients who wish to override just part of the
    272 // functionality of another Env.
    273 class EnvWrapper : public Env {
    274  public:
    275   // Initialize an EnvWrapper that delegates all calls to *t
    276   explicit EnvWrapper(Env* t) : target_(t) { }
    277   virtual ~EnvWrapper();
    278 
    279   // Return the target to which this Env forwards all calls
    280   Env* target() const { return target_; }
    281 
    282   // The following text is boilerplate that forwards all methods to target()
    283   Status NewSequentialFile(const std::string& f, SequentialFile** r) {
    284     return target_->NewSequentialFile(f, r);
    285   }
    286   Status NewRandomAccessFile(const std::string& f, RandomAccessFile** r) {
    287     return target_->NewRandomAccessFile(f, r);
    288   }
    289   Status NewWritableFile(const std::string& f, WritableFile** r) {
    290     return target_->NewWritableFile(f, r);
    291   }
    292   bool FileExists(const std::string& f) { return target_->FileExists(f); }
    293   Status GetChildren(const std::string& dir, std::vector<std::string>* r) {
    294     return target_->GetChildren(dir, r);
    295   }
    296   Status DeleteFile(const std::string& f) { return target_->DeleteFile(f); }
    297   Status CreateDir(const std::string& d) { return target_->CreateDir(d); }
    298   Status DeleteDir(const std::string& d) { return target_->DeleteDir(d); }
    299   Status GetFileSize(const std::string& f, uint64_t* s) {
    300     return target_->GetFileSize(f, s);
    301   }
    302   Status RenameFile(const std::string& s, const std::string& t) {
    303     return target_->RenameFile(s, t);
    304   }
    305   Status LockFile(const std::string& f, FileLock** l) {
    306     return target_->LockFile(f, l);
    307   }
    308   Status UnlockFile(FileLock* l) { return target_->UnlockFile(l); }
    309   void Schedule(void (*f)(void*), void* a) {
    310     return target_->Schedule(f, a);
    311   }
    312   void StartThread(void (*f)(void*), void* a) {
    313     return target_->StartThread(f, a);
    314   }
    315   virtual Status GetTestDirectory(std::string* path) {
    316     return target_->GetTestDirectory(path);
    317   }
    318   virtual Status NewLogger(const std::string& fname, Logger** result) {
    319     return target_->NewLogger(fname, result);
    320   }
    321   uint64_t NowMicros() {
    322     return target_->NowMicros();
    323   }
    324   void SleepForMicroseconds(int micros) {
    325     target_->SleepForMicroseconds(micros);
    326   }
    327  private:
    328   Env* target_;
    329 };
    330 
    331 }  // namespace leveldb
    332 
    333 #endif  // STORAGE_LEVELDB_INCLUDE_ENV_H_
    334