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