You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

env.h 13KB

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