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.
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.
10 // All Env implementations are safe for concurrent access from
11 // multiple threads without any external synchronization.
13 #ifndef STORAGE_LEVELDB_INCLUDE_ENV_H_
14 #define STORAGE_LEVELDB_INCLUDE_ENV_H_
20 #include "leveldb/status.h"
26 class RandomAccessFile;
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.
40 // The result of Default() belongs to leveldb and must never be deleted.
41 static Env* Default();
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.
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;
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
58 // The returned file may be concurrently accessed by multiple threads.
59 virtual Status NewRandomAccessFile(const std::string& fname,
60 RandomAccessFile** result) = 0;
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
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;
72 // Returns true iff the named file exists.
73 virtual bool FileExists(const std::string& fname) = 0;
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;
81 // Delete the named file.
82 virtual Status DeleteFile(const std::string& fname) = 0;
84 // Create the specified directory.
85 virtual Status CreateDir(const std::string& dirname) = 0;
87 // Delete the specified directory.
88 virtual Status DeleteDir(const std::string& dirname) = 0;
90 // Store the size of fname in *file_size.
91 virtual Status GetFileSize(const std::string& fname, uint64_t* file_size) = 0;
93 // Rename file src to target.
94 virtual Status RenameFile(const std::string& src,
95 const std::string& target) = 0;
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.
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.
106 // If somebody else already holds the lock, finishes immediately
107 // with a failure. I.e., this call does not wait for existing locks
110 // May create the named file if it does not already exist.
111 virtual Status LockFile(const std::string& fname, FileLock** lock) = 0;
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;
118 // Arrange to run "(*function)(arg)" once in a background thread.
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
124 virtual void Schedule(
125 void (*function)(void* arg),
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;
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
136 virtual Status GetTestDirectory(std::string* path) = 0;
138 // Create and return a log file for storing informational messages.
139 virtual Status NewLogger(const std::string& fname, Logger** result) = 0;
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;
145 // Sleep/delay the thread for the perscribed number of micro-seconds.
146 virtual void SleepForMicroseconds(int micros) = 0;
149 // No copying allowed
151 void operator=(const Env&);
154 // A file abstraction for reading sequentially through a file
155 class SequentialFile {
158 virtual ~SequentialFile();
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.
167 // REQUIRES: External synchronization
168 virtual Status Read(size_t n, Slice* result, char* scratch) = 0;
170 // Skip "n" bytes from the file. This is guaranteed to be no
171 // slower that reading the same data, but may be faster.
173 // If end of file is reached, skipping will stop at the end of the
174 // file, and Skip will return OK.
176 // REQUIRES: External synchronization
177 virtual Status Skip(uint64_t n) = 0;
180 // No copying allowed
181 SequentialFile(const SequentialFile&);
182 void operator=(const SequentialFile&);
185 // A file abstraction for randomly reading the contents of a file.
186 class RandomAccessFile {
188 RandomAccessFile() { }
189 virtual ~RandomAccessFile();
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
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;
204 // No copying allowed
205 RandomAccessFile(const RandomAccessFile&);
206 void operator=(const RandomAccessFile&);
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.
215 virtual ~WritableFile();
217 virtual Status Append(const Slice& data) = 0;
218 virtual Status Close() = 0;
219 virtual Status Flush() = 0;
220 virtual Status Sync() = 0;
223 // No copying allowed
224 WritableFile(const WritableFile&);
225 void operator=(const WritableFile&);
228 // An interface for writing log messages.
234 // Write an entry to the log file with the specified format.
235 virtual void Logv(const char* format, va_list ap) = 0;
238 // No copying allowed
239 Logger(const Logger&);
240 void operator=(const Logger&);
244 // Identifies a locked file.
250 // No copying allowed
251 FileLock(const FileLock&);
252 void operator=(const FileLock&);
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)))
262 // A utility routine: write "data" to the named file.
263 extern Status WriteStringToFile(Env* env, const Slice& data,
264 const std::string& fname);
266 // A utility routine: read contents of named file into *data
267 extern Status ReadFileToString(Env* env, const std::string& fname,
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 {
275 // Initialize an EnvWrapper that delegates all calls to *t
276 explicit EnvWrapper(Env* t) : target_(t) { }
277 virtual ~EnvWrapper();
279 // Return the target to which this Env forwards all calls
280 Env* target() const { return target_; }
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);
286 Status NewRandomAccessFile(const std::string& f, RandomAccessFile** r) {
287 return target_->NewRandomAccessFile(f, r);
289 Status NewWritableFile(const std::string& f, WritableFile** r) {
290 return target_->NewWritableFile(f, r);
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);
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);
302 Status RenameFile(const std::string& s, const std::string& t) {
303 return target_->RenameFile(s, t);
305 Status LockFile(const std::string& f, FileLock** l) {
306 return target_->LockFile(f, l);
308 Status UnlockFile(FileLock* l) { return target_->UnlockFile(l); }
309 void Schedule(void (*f)(void*), void* a) {
310 return target_->Schedule(f, a);
312 void StartThread(void (*f)(void*), void* a) {
313 return target_->StartThread(f, a);
315 virtual Status GetTestDirectory(std::string* path) {
316 return target_->GetTestDirectory(path);
318 virtual Status NewLogger(const std::string& fname, Logger** result) {
319 return target_->NewLogger(fname, result);
321 uint64_t NowMicros() {
322 return target_->NowMicros();
324 void SleepForMicroseconds(int micros) {
325 target_->SleepForMicroseconds(micros);
331 } // namespace leveldb
333 #endif // STORAGE_LEVELDB_INCLUDE_ENV_H_