LevelDB project 1 10225501460 林子骥 10211900416 郭夏辉
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.

425 regels
16 KiB

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