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