]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/include/rocksdb/env.h
import 14.2.4 nautilus point release
[ceph.git] / ceph / src / rocksdb / include / rocksdb / env.h
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
5 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
6 // Use of this source code is governed by a BSD-style license that can be
7 // found in the LICENSE file. See the AUTHORS file for names of contributors.
8 //
9 // An Env is an interface used by the rocksdb implementation to access
10 // operating system functionality like the filesystem etc. Callers
11 // may wish to provide a custom Env object when opening a database to
12 // get fine gain control; e.g., to rate limit file system operations.
13 //
14 // All Env implementations are safe for concurrent access from
15 // multiple threads without any external synchronization.
16
17 #pragma once
18
19 #include <stdint.h>
20 #include <cstdarg>
21 #include <functional>
22 #include <limits>
23 #include <memory>
24 #include <string>
25 #include <vector>
26 #include "rocksdb/status.h"
27 #include "rocksdb/thread_status.h"
28
29 #ifdef _WIN32
30 // Windows API macro interference
31 #undef DeleteFile
32 #undef GetCurrentTime
33 #endif
34
35 #if defined(__GNUC__) || defined(__clang__)
36 #define ROCKSDB_PRINTF_FORMAT_ATTR(format_param, dots_param) \
37 __attribute__((__format__(__printf__, format_param, dots_param)))
38 #else
39 #define ROCKSDB_PRINTF_FORMAT_ATTR(format_param, dots_param)
40 #endif
41
42 namespace rocksdb {
43
44 class FileLock;
45 class Logger;
46 class RandomAccessFile;
47 class SequentialFile;
48 class Slice;
49 class WritableFile;
50 class RandomRWFile;
51 class MemoryMappedFileBuffer;
52 class Directory;
53 struct DBOptions;
54 struct ImmutableDBOptions;
55 struct MutableDBOptions;
56 class RateLimiter;
57 class ThreadStatusUpdater;
58 struct ThreadStatus;
59
60 const size_t kDefaultPageSize = 4 * 1024;
61
62 // Options while opening a file to read/write
63 struct EnvOptions {
64 // Construct with default Options
65 EnvOptions();
66
67 // Construct from Options
68 explicit EnvOptions(const DBOptions& options);
69
70 // If true, then use mmap to read data
71 bool use_mmap_reads = false;
72
73 // If true, then use mmap to write data
74 bool use_mmap_writes = true;
75
76 // If true, then use O_DIRECT for reading data
77 bool use_direct_reads = false;
78
79 // If true, then use O_DIRECT for writing data
80 bool use_direct_writes = false;
81
82 // If false, fallocate() calls are bypassed
83 bool allow_fallocate = true;
84
85 // If true, set the FD_CLOEXEC on open fd.
86 bool set_fd_cloexec = true;
87
88 // Allows OS to incrementally sync files to disk while they are being
89 // written, in the background. Issue one request for every bytes_per_sync
90 // written. 0 turns it off.
91 // Default: 0
92 uint64_t bytes_per_sync = 0;
93
94 // If true, we will preallocate the file with FALLOC_FL_KEEP_SIZE flag, which
95 // means that file size won't change as part of preallocation.
96 // If false, preallocation will also change the file size. This option will
97 // improve the performance in workloads where you sync the data on every
98 // write. By default, we set it to true for MANIFEST writes and false for
99 // WAL writes
100 bool fallocate_with_keep_size = true;
101
102 // See DBOptions doc
103 size_t compaction_readahead_size;
104
105 // See DBOptions doc
106 size_t random_access_max_buffer_size;
107
108 // See DBOptions doc
109 size_t writable_file_max_buffer_size = 1024 * 1024;
110
111 // If not nullptr, write rate limiting is enabled for flush and compaction
112 RateLimiter* rate_limiter = nullptr;
113 };
114
115 class Env {
116 public:
117 struct FileAttributes {
118 // File name
119 std::string name;
120
121 // Size of file in bytes
122 uint64_t size_bytes;
123 };
124
125 Env() : thread_status_updater_(nullptr) {}
126
127 virtual ~Env();
128
129 // Return a default environment suitable for the current operating
130 // system. Sophisticated users may wish to provide their own Env
131 // implementation instead of relying on this default environment.
132 //
133 // The result of Default() belongs to rocksdb and must never be deleted.
134 static Env* Default();
135
136 // Create a brand new sequentially-readable file with the specified name.
137 // On success, stores a pointer to the new file in *result and returns OK.
138 // On failure stores nullptr in *result and returns non-OK. If the file does
139 // not exist, returns a non-OK status.
140 //
141 // The returned file will only be accessed by one thread at a time.
142 virtual Status NewSequentialFile(const std::string& fname,
143 std::unique_ptr<SequentialFile>* result,
144 const EnvOptions& options) = 0;
145
146 // Create a brand new random access read-only file with the
147 // specified name. On success, stores a pointer to the new file in
148 // *result and returns OK. On failure stores nullptr in *result and
149 // returns non-OK. If the file does not exist, returns a non-OK
150 // status.
151 //
152 // The returned file may be concurrently accessed by multiple threads.
153 virtual Status NewRandomAccessFile(const std::string& fname,
154 std::unique_ptr<RandomAccessFile>* result,
155 const EnvOptions& options) = 0;
156 // These values match Linux definition
157 // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/fcntl.h#n56
158 enum WriteLifeTimeHint {
159 WLTH_NOT_SET = 0, // No hint information set
160 WLTH_NONE, // No hints about write life time
161 WLTH_SHORT, // Data written has a short life time
162 WLTH_MEDIUM, // Data written has a medium life time
163 WLTH_LONG, // Data written has a long life time
164 WLTH_EXTREME, // Data written has an extremely long life time
165 };
166
167 // Create an object that writes to a new file with the specified
168 // name. Deletes any existing file with the same name and creates a
169 // new file. On success, stores a pointer to the new file in
170 // *result and returns OK. On failure stores nullptr in *result and
171 // returns non-OK.
172 //
173 // The returned file will only be accessed by one thread at a time.
174 virtual Status NewWritableFile(const std::string& fname,
175 std::unique_ptr<WritableFile>* result,
176 const EnvOptions& options) = 0;
177
178 // Create an object that writes to a new file with the specified
179 // name. Deletes any existing file with the same name and creates a
180 // new file. On success, stores a pointer to the new file in
181 // *result and returns OK. On failure stores nullptr in *result and
182 // returns non-OK.
183 //
184 // The returned file will only be accessed by one thread at a time.
185 virtual Status ReopenWritableFile(const std::string& /*fname*/,
186 std::unique_ptr<WritableFile>* /*result*/,
187 const EnvOptions& /*options*/) {
188 return Status::NotSupported();
189 }
190
191 // Reuse an existing file by renaming it and opening it as writable.
192 virtual Status ReuseWritableFile(const std::string& fname,
193 const std::string& old_fname,
194 std::unique_ptr<WritableFile>* result,
195 const EnvOptions& options);
196
197 // Open `fname` for random read and write, if file doesn't exist the file
198 // will be created. On success, stores a pointer to the new file in
199 // *result and returns OK. On failure returns non-OK.
200 //
201 // The returned file will only be accessed by one thread at a time.
202 virtual Status NewRandomRWFile(const std::string& /*fname*/,
203 std::unique_ptr<RandomRWFile>* /*result*/,
204 const EnvOptions& /*options*/) {
205 return Status::NotSupported("RandomRWFile is not implemented in this Env");
206 }
207
208 // Opens `fname` as a memory-mapped file for read and write (in-place updates
209 // only, i.e., no appends). On success, stores a raw buffer covering the whole
210 // file in `*result`. The file must exist prior to this call.
211 virtual Status NewMemoryMappedFileBuffer(
212 const std::string& /*fname*/,
213 std::unique_ptr<MemoryMappedFileBuffer>* /*result*/) {
214 return Status::NotSupported(
215 "MemoryMappedFileBuffer is not implemented in this Env");
216 }
217
218 // Create an object that represents a directory. Will fail if directory
219 // doesn't exist. If the directory exists, it will open the directory
220 // and create a new Directory object.
221 //
222 // On success, stores a pointer to the new Directory in
223 // *result and returns OK. On failure stores nullptr in *result and
224 // returns non-OK.
225 virtual Status NewDirectory(const std::string& name,
226 std::unique_ptr<Directory>* result) = 0;
227
228 // Returns OK if the named file exists.
229 // NotFound if the named file does not exist,
230 // the calling process does not have permission to determine
231 // whether this file exists, or if the path is invalid.
232 // IOError if an IO Error was encountered
233 virtual Status FileExists(const std::string& fname) = 0;
234
235 // Store in *result the names of the children of the specified directory.
236 // The names are relative to "dir".
237 // Original contents of *results are dropped.
238 // Returns OK if "dir" exists and "*result" contains its children.
239 // NotFound if "dir" does not exist, the calling process does not have
240 // permission to access "dir", or if "dir" is invalid.
241 // IOError if an IO Error was encountered
242 virtual Status GetChildren(const std::string& dir,
243 std::vector<std::string>* result) = 0;
244
245 // Store in *result the attributes of the children of the specified directory.
246 // In case the implementation lists the directory prior to iterating the files
247 // and files are concurrently deleted, the deleted files will be omitted from
248 // result.
249 // The name attributes are relative to "dir".
250 // Original contents of *results are dropped.
251 // Returns OK if "dir" exists and "*result" contains its children.
252 // NotFound if "dir" does not exist, the calling process does not have
253 // permission to access "dir", or if "dir" is invalid.
254 // IOError if an IO Error was encountered
255 virtual Status GetChildrenFileAttributes(const std::string& dir,
256 std::vector<FileAttributes>* result);
257
258 // Delete the named file.
259 virtual Status DeleteFile(const std::string& fname) = 0;
260
261 // Truncate the named file to the specified size.
262 virtual Status Truncate(const std::string& /*fname*/, size_t /*size*/) {
263 return Status::NotSupported("Truncate is not supported for this Env");
264 }
265
266 // Create the specified directory. Returns error if directory exists.
267 virtual Status CreateDir(const std::string& dirname) = 0;
268
269 // Creates directory if missing. Return Ok if it exists, or successful in
270 // Creating.
271 virtual Status CreateDirIfMissing(const std::string& dirname) = 0;
272
273 // Delete the specified directory.
274 virtual Status DeleteDir(const std::string& dirname) = 0;
275
276 // Store the size of fname in *file_size.
277 virtual Status GetFileSize(const std::string& fname, uint64_t* file_size) = 0;
278
279 // Store the last modification time of fname in *file_mtime.
280 virtual Status GetFileModificationTime(const std::string& fname,
281 uint64_t* file_mtime) = 0;
282 // Rename file src to target.
283 virtual Status RenameFile(const std::string& src,
284 const std::string& target) = 0;
285
286 // Hard Link file src to target.
287 virtual Status LinkFile(const std::string& /*src*/,
288 const std::string& /*target*/) {
289 return Status::NotSupported("LinkFile is not supported for this Env");
290 }
291
292 virtual Status NumFileLinks(const std::string& /*fname*/,
293 uint64_t* /*count*/) {
294 return Status::NotSupported(
295 "Getting number of file links is not supported for this Env");
296 }
297
298 virtual Status AreFilesSame(const std::string& /*first*/,
299 const std::string& /*second*/, bool* /*res*/) {
300 return Status::NotSupported("AreFilesSame is not supported for this Env");
301 }
302
303 // Lock the specified file. Used to prevent concurrent access to
304 // the same db by multiple processes. On failure, stores nullptr in
305 // *lock and returns non-OK.
306 //
307 // On success, stores a pointer to the object that represents the
308 // acquired lock in *lock and returns OK. The caller should call
309 // UnlockFile(*lock) to release the lock. If the process exits,
310 // the lock will be automatically released.
311 //
312 // If somebody else already holds the lock, finishes immediately
313 // with a failure. I.e., this call does not wait for existing locks
314 // to go away.
315 //
316 // May create the named file if it does not already exist.
317 virtual Status LockFile(const std::string& fname, FileLock** lock) = 0;
318
319 // Release the lock acquired by a previous successful call to LockFile.
320 // REQUIRES: lock was returned by a successful LockFile() call
321 // REQUIRES: lock has not already been unlocked.
322 virtual Status UnlockFile(FileLock* lock) = 0;
323
324 // Priority for scheduling job in thread pool
325 enum Priority { BOTTOM, LOW, HIGH, USER, TOTAL };
326
327 static std::string PriorityToString(Priority priority);
328
329 // Priority for requesting bytes in rate limiter scheduler
330 enum IOPriority { IO_LOW = 0, IO_HIGH = 1, IO_TOTAL = 2 };
331
332 // Arrange to run "(*function)(arg)" once in a background thread, in
333 // the thread pool specified by pri. By default, jobs go to the 'LOW'
334 // priority thread pool.
335
336 // "function" may run in an unspecified thread. Multiple functions
337 // added to the same Env may run concurrently in different threads.
338 // I.e., the caller may not assume that background work items are
339 // serialized.
340 // When the UnSchedule function is called, the unschedFunction
341 // registered at the time of Schedule is invoked with arg as a parameter.
342 virtual void Schedule(void (*function)(void* arg), void* arg,
343 Priority pri = LOW, void* tag = nullptr,
344 void (*unschedFunction)(void* arg) = nullptr) = 0;
345
346 // Arrange to remove jobs for given arg from the queue_ if they are not
347 // already scheduled. Caller is expected to have exclusive lock on arg.
348 virtual int UnSchedule(void* /*arg*/, Priority /*pri*/) { return 0; }
349
350 // Start a new thread, invoking "function(arg)" within the new thread.
351 // When "function(arg)" returns, the thread will be destroyed.
352 virtual void StartThread(void (*function)(void* arg), void* arg) = 0;
353
354 // Wait for all threads started by StartThread to terminate.
355 virtual void WaitForJoin() {}
356
357 // Get thread pool queue length for specific thread pool.
358 virtual unsigned int GetThreadPoolQueueLen(Priority /*pri*/ = LOW) const {
359 return 0;
360 }
361
362 // *path is set to a temporary directory that can be used for testing. It may
363 // or many not have just been created. The directory may or may not differ
364 // between runs of the same process, but subsequent calls will return the
365 // same directory.
366 virtual Status GetTestDirectory(std::string* path) = 0;
367
368 // Create and return a log file for storing informational messages.
369 virtual Status NewLogger(const std::string& fname,
370 std::shared_ptr<Logger>* result) = 0;
371
372 // Returns the number of micro-seconds since some fixed point in time.
373 // It is often used as system time such as in GenericRateLimiter
374 // and other places so a port needs to return system time in order to work.
375 virtual uint64_t NowMicros() = 0;
376
377 // Returns the number of nano-seconds since some fixed point in time. Only
378 // useful for computing deltas of time in one run.
379 // Default implementation simply relies on NowMicros.
380 // In platform-specific implementations, NowNanos() should return time points
381 // that are MONOTONIC.
382 virtual uint64_t NowNanos() { return NowMicros() * 1000; }
383
384 // 0 indicates not supported.
385 virtual uint64_t NowCPUNanos() { return 0; }
386
387 // Sleep/delay the thread for the prescribed number of micro-seconds.
388 virtual void SleepForMicroseconds(int micros) = 0;
389
390 // Get the current host name.
391 virtual Status GetHostName(char* name, uint64_t len) = 0;
392
393 // Get the number of seconds since the Epoch, 1970-01-01 00:00:00 (UTC).
394 // Only overwrites *unix_time on success.
395 virtual Status GetCurrentTime(int64_t* unix_time) = 0;
396
397 // Get full directory name for this db.
398 virtual Status GetAbsolutePath(const std::string& db_path,
399 std::string* output_path) = 0;
400
401 // The number of background worker threads of a specific thread pool
402 // for this environment. 'LOW' is the default pool.
403 // default number: 1
404 virtual void SetBackgroundThreads(int number, Priority pri = LOW) = 0;
405 virtual int GetBackgroundThreads(Priority pri = LOW) = 0;
406
407 virtual Status SetAllowNonOwnerAccess(bool /*allow_non_owner_access*/) {
408 return Status::NotSupported("Not supported.");
409 }
410
411 // Enlarge number of background worker threads of a specific thread pool
412 // for this environment if it is smaller than specified. 'LOW' is the default
413 // pool.
414 virtual void IncBackgroundThreadsIfNeeded(int number, Priority pri) = 0;
415
416 // Lower IO priority for threads from the specified pool.
417 virtual void LowerThreadPoolIOPriority(Priority /*pool*/ = LOW) {}
418
419 // Lower CPU priority for threads from the specified pool.
420 virtual void LowerThreadPoolCPUPriority(Priority /*pool*/ = LOW) {}
421
422 // Converts seconds-since-Jan-01-1970 to a printable string
423 virtual std::string TimeToString(uint64_t time) = 0;
424
425 // Generates a unique id that can be used to identify a db
426 virtual std::string GenerateUniqueId();
427
428 // OptimizeForLogWrite will create a new EnvOptions object that is a copy of
429 // the EnvOptions in the parameters, but is optimized for reading log files.
430 virtual EnvOptions OptimizeForLogRead(const EnvOptions& env_options) const;
431
432 // OptimizeForManifestRead will create a new EnvOptions object that is a copy
433 // of the EnvOptions in the parameters, but is optimized for reading manifest
434 // files.
435 virtual EnvOptions OptimizeForManifestRead(
436 const EnvOptions& env_options) const;
437
438 // OptimizeForLogWrite will create a new EnvOptions object that is a copy of
439 // the EnvOptions in the parameters, but is optimized for writing log files.
440 // Default implementation returns the copy of the same object.
441 virtual EnvOptions OptimizeForLogWrite(const EnvOptions& env_options,
442 const DBOptions& db_options) const;
443 // OptimizeForManifestWrite will create a new EnvOptions object that is a copy
444 // of the EnvOptions in the parameters, but is optimized for writing manifest
445 // files. Default implementation returns the copy of the same object.
446 virtual EnvOptions OptimizeForManifestWrite(
447 const EnvOptions& env_options) const;
448
449 // OptimizeForCompactionTableWrite will create a new EnvOptions object that is
450 // a copy of the EnvOptions in the parameters, but is optimized for writing
451 // table files.
452 virtual EnvOptions OptimizeForCompactionTableWrite(
453 const EnvOptions& env_options,
454 const ImmutableDBOptions& immutable_ops) const;
455
456 // OptimizeForCompactionTableWrite will create a new EnvOptions object that
457 // is a copy of the EnvOptions in the parameters, but is optimized for reading
458 // table files.
459 virtual EnvOptions OptimizeForCompactionTableRead(
460 const EnvOptions& env_options,
461 const ImmutableDBOptions& db_options) const;
462
463 // Returns the status of all threads that belong to the current Env.
464 virtual Status GetThreadList(std::vector<ThreadStatus>* /*thread_list*/) {
465 return Status::NotSupported("Not supported.");
466 }
467
468 // Returns the pointer to ThreadStatusUpdater. This function will be
469 // used in RocksDB internally to update thread status and supports
470 // GetThreadList().
471 virtual ThreadStatusUpdater* GetThreadStatusUpdater() const {
472 return thread_status_updater_;
473 }
474
475 // Returns the ID of the current thread.
476 virtual uint64_t GetThreadID() const;
477
478 // This seems to clash with a macro on Windows, so #undef it here
479 #undef GetFreeSpace
480
481 // Get the amount of free disk space
482 virtual Status GetFreeSpace(const std::string& /*path*/,
483 uint64_t* /*diskfree*/) {
484 return Status::NotSupported();
485 }
486
487 // If you're adding methods here, remember to add them to EnvWrapper too.
488
489 protected:
490 // The pointer to an internal structure that will update the
491 // status of each thread.
492 ThreadStatusUpdater* thread_status_updater_;
493
494 private:
495 // No copying allowed
496 Env(const Env&);
497 void operator=(const Env&);
498 };
499
500 // The factory function to construct a ThreadStatusUpdater. Any Env
501 // that supports GetThreadList() feature should call this function in its
502 // constructor to initialize thread_status_updater_.
503 ThreadStatusUpdater* CreateThreadStatusUpdater();
504
505 // A file abstraction for reading sequentially through a file
506 class SequentialFile {
507 public:
508 SequentialFile() {}
509 virtual ~SequentialFile();
510
511 // Read up to "n" bytes from the file. "scratch[0..n-1]" may be
512 // written by this routine. Sets "*result" to the data that was
513 // read (including if fewer than "n" bytes were successfully read).
514 // May set "*result" to point at data in "scratch[0..n-1]", so
515 // "scratch[0..n-1]" must be live when "*result" is used.
516 // If an error was encountered, returns a non-OK status.
517 //
518 // REQUIRES: External synchronization
519 virtual Status Read(size_t n, Slice* result, char* scratch) = 0;
520
521 // Skip "n" bytes from the file. This is guaranteed to be no
522 // slower that reading the same data, but may be faster.
523 //
524 // If end of file is reached, skipping will stop at the end of the
525 // file, and Skip will return OK.
526 //
527 // REQUIRES: External synchronization
528 virtual Status Skip(uint64_t n) = 0;
529
530 // Indicates the upper layers if the current SequentialFile implementation
531 // uses direct IO.
532 virtual bool use_direct_io() const { return false; }
533
534 // Use the returned alignment value to allocate
535 // aligned buffer for Direct I/O
536 virtual size_t GetRequiredBufferAlignment() const { return kDefaultPageSize; }
537
538 // Remove any kind of caching of data from the offset to offset+length
539 // of this file. If the length is 0, then it refers to the end of file.
540 // If the system is not caching the file contents, then this is a noop.
541 virtual Status InvalidateCache(size_t /*offset*/, size_t /*length*/) {
542 return Status::NotSupported("InvalidateCache not supported.");
543 }
544
545 // Positioned Read for direct I/O
546 // If Direct I/O enabled, offset, n, and scratch should be properly aligned
547 virtual Status PositionedRead(uint64_t /*offset*/, size_t /*n*/,
548 Slice* /*result*/, char* /*scratch*/) {
549 return Status::NotSupported();
550 }
551
552 // If you're adding methods here, remember to add them to
553 // SequentialFileWrapper too.
554 };
555
556 // A file abstraction for randomly reading the contents of a file.
557 class RandomAccessFile {
558 public:
559 RandomAccessFile() {}
560 virtual ~RandomAccessFile();
561
562 // Read up to "n" bytes from the file starting at "offset".
563 // "scratch[0..n-1]" may be written by this routine. Sets "*result"
564 // to the data that was read (including if fewer than "n" bytes were
565 // successfully read). May set "*result" to point at data in
566 // "scratch[0..n-1]", so "scratch[0..n-1]" must be live when
567 // "*result" is used. If an error was encountered, returns a non-OK
568 // status.
569 //
570 // Safe for concurrent use by multiple threads.
571 // If Direct I/O enabled, offset, n, and scratch should be aligned properly.
572 virtual Status Read(uint64_t offset, size_t n, Slice* result,
573 char* scratch) const = 0;
574
575 // Readahead the file starting from offset by n bytes for caching.
576 virtual Status Prefetch(uint64_t /*offset*/, size_t /*n*/) {
577 return Status::OK();
578 }
579
580 // Tries to get an unique ID for this file that will be the same each time
581 // the file is opened (and will stay the same while the file is open).
582 // Furthermore, it tries to make this ID at most "max_size" bytes. If such an
583 // ID can be created this function returns the length of the ID and places it
584 // in "id"; otherwise, this function returns 0, in which case "id"
585 // may not have been modified.
586 //
587 // This function guarantees, for IDs from a given environment, two unique ids
588 // cannot be made equal to each other by adding arbitrary bytes to one of
589 // them. That is, no unique ID is the prefix of another.
590 //
591 // This function guarantees that the returned ID will not be interpretable as
592 // a single varint.
593 //
594 // Note: these IDs are only valid for the duration of the process.
595 virtual size_t GetUniqueId(char* /*id*/, size_t /*max_size*/) const {
596 return 0; // Default implementation to prevent issues with backwards
597 // compatibility.
598 };
599
600 enum AccessPattern { NORMAL, RANDOM, SEQUENTIAL, WILLNEED, DONTNEED };
601
602 virtual void Hint(AccessPattern /*pattern*/) {}
603
604 // Indicates the upper layers if the current RandomAccessFile implementation
605 // uses direct IO.
606 virtual bool use_direct_io() const { return false; }
607
608 // Use the returned alignment value to allocate
609 // aligned buffer for Direct I/O
610 virtual size_t GetRequiredBufferAlignment() const { return kDefaultPageSize; }
611
612 // Remove any kind of caching of data from the offset to offset+length
613 // of this file. If the length is 0, then it refers to the end of file.
614 // If the system is not caching the file contents, then this is a noop.
615 virtual Status InvalidateCache(size_t /*offset*/, size_t /*length*/) {
616 return Status::NotSupported("InvalidateCache not supported.");
617 }
618
619 // If you're adding methods here, remember to add them to
620 // RandomAccessFileWrapper too.
621 };
622
623 // A file abstraction for sequential writing. The implementation
624 // must provide buffering since callers may append small fragments
625 // at a time to the file.
626 class WritableFile {
627 public:
628 WritableFile()
629 : last_preallocated_block_(0),
630 preallocation_block_size_(0),
631 io_priority_(Env::IO_TOTAL),
632 write_hint_(Env::WLTH_NOT_SET) {}
633 virtual ~WritableFile();
634
635 // Append data to the end of the file
636 // Note: A WriteabelFile object must support either Append or
637 // PositionedAppend, so the users cannot mix the two.
638 virtual Status Append(const Slice& data) = 0;
639
640 // PositionedAppend data to the specified offset. The new EOF after append
641 // must be larger than the previous EOF. This is to be used when writes are
642 // not backed by OS buffers and hence has to always start from the start of
643 // the sector. The implementation thus needs to also rewrite the last
644 // partial sector.
645 // Note: PositionAppend does not guarantee moving the file offset after the
646 // write. A WritableFile object must support either Append or
647 // PositionedAppend, so the users cannot mix the two.
648 //
649 // PositionedAppend() can only happen on the page/sector boundaries. For that
650 // reason, if the last write was an incomplete sector we still need to rewind
651 // back to the nearest sector/page and rewrite the portion of it with whatever
652 // we need to add. We need to keep where we stop writing.
653 //
654 // PositionedAppend() can only write whole sectors. For that reason we have to
655 // pad with zeros for the last write and trim the file when closing according
656 // to the position we keep in the previous step.
657 //
658 // PositionedAppend() requires aligned buffer to be passed in. The alignment
659 // required is queried via GetRequiredBufferAlignment()
660 virtual Status PositionedAppend(const Slice& /* data */,
661 uint64_t /* offset */) {
662 return Status::NotSupported();
663 }
664
665 // Truncate is necessary to trim the file to the correct size
666 // before closing. It is not always possible to keep track of the file
667 // size due to whole pages writes. The behavior is undefined if called
668 // with other writes to follow.
669 virtual Status Truncate(uint64_t /*size*/) { return Status::OK(); }
670 virtual Status Close() = 0;
671 virtual Status Flush() = 0;
672 virtual Status Sync() = 0; // sync data
673
674 /*
675 * Sync data and/or metadata as well.
676 * By default, sync only data.
677 * Override this method for environments where we need to sync
678 * metadata as well.
679 */
680 virtual Status Fsync() { return Sync(); }
681
682 // true if Sync() and Fsync() are safe to call concurrently with Append()
683 // and Flush().
684 virtual bool IsSyncThreadSafe() const { return false; }
685
686 // Indicates the upper layers if the current WritableFile implementation
687 // uses direct IO.
688 virtual bool use_direct_io() const { return false; }
689
690 // Use the returned alignment value to allocate
691 // aligned buffer for Direct I/O
692 virtual size_t GetRequiredBufferAlignment() const { return kDefaultPageSize; }
693 /*
694 * Change the priority in rate limiter if rate limiting is enabled.
695 * If rate limiting is not enabled, this call has no effect.
696 */
697 virtual void SetIOPriority(Env::IOPriority pri) { io_priority_ = pri; }
698
699 virtual Env::IOPriority GetIOPriority() { return io_priority_; }
700
701 virtual void SetWriteLifeTimeHint(Env::WriteLifeTimeHint hint) {
702 write_hint_ = hint;
703 }
704
705 virtual Env::WriteLifeTimeHint GetWriteLifeTimeHint() { return write_hint_; }
706 /*
707 * Get the size of valid data in the file.
708 */
709 virtual uint64_t GetFileSize() { return 0; }
710
711 /*
712 * Get and set the default pre-allocation block size for writes to
713 * this file. If non-zero, then Allocate will be used to extend the
714 * underlying storage of a file (generally via fallocate) if the Env
715 * instance supports it.
716 */
717 virtual void SetPreallocationBlockSize(size_t size) {
718 preallocation_block_size_ = size;
719 }
720
721 virtual void GetPreallocationStatus(size_t* block_size,
722 size_t* last_allocated_block) {
723 *last_allocated_block = last_preallocated_block_;
724 *block_size = preallocation_block_size_;
725 }
726
727 // For documentation, refer to RandomAccessFile::GetUniqueId()
728 virtual size_t GetUniqueId(char* /*id*/, size_t /*max_size*/) const {
729 return 0; // Default implementation to prevent issues with backwards
730 }
731
732 // Remove any kind of caching of data from the offset to offset+length
733 // of this file. If the length is 0, then it refers to the end of file.
734 // If the system is not caching the file contents, then this is a noop.
735 // This call has no effect on dirty pages in the cache.
736 virtual Status InvalidateCache(size_t /*offset*/, size_t /*length*/) {
737 return Status::NotSupported("InvalidateCache not supported.");
738 }
739
740 // Sync a file range with disk.
741 // offset is the starting byte of the file range to be synchronized.
742 // nbytes specifies the length of the range to be synchronized.
743 // This asks the OS to initiate flushing the cached data to disk,
744 // without waiting for completion.
745 // Default implementation does nothing.
746 virtual Status RangeSync(uint64_t /*offset*/, uint64_t /*nbytes*/) {
747 return Status::OK();
748 }
749
750 // PrepareWrite performs any necessary preparation for a write
751 // before the write actually occurs. This allows for pre-allocation
752 // of space on devices where it can result in less file
753 // fragmentation and/or less waste from over-zealous filesystem
754 // pre-allocation.
755 virtual void PrepareWrite(size_t offset, size_t len) {
756 if (preallocation_block_size_ == 0) {
757 return;
758 }
759 // If this write would cross one or more preallocation blocks,
760 // determine what the last preallocation block necessary to
761 // cover this write would be and Allocate to that point.
762 const auto block_size = preallocation_block_size_;
763 size_t new_last_preallocated_block =
764 (offset + len + block_size - 1) / block_size;
765 if (new_last_preallocated_block > last_preallocated_block_) {
766 size_t num_spanned_blocks =
767 new_last_preallocated_block - last_preallocated_block_;
768 Allocate(block_size * last_preallocated_block_,
769 block_size * num_spanned_blocks);
770 last_preallocated_block_ = new_last_preallocated_block;
771 }
772 }
773
774 // Pre-allocates space for a file.
775 virtual Status Allocate(uint64_t /*offset*/, uint64_t /*len*/) {
776 return Status::OK();
777 }
778
779 // If you're adding methods here, remember to add them to
780 // WritableFileWrapper too.
781
782 protected:
783 size_t preallocation_block_size() { return preallocation_block_size_; }
784
785 private:
786 size_t last_preallocated_block_;
787 size_t preallocation_block_size_;
788 // No copying allowed
789 WritableFile(const WritableFile&);
790 void operator=(const WritableFile&);
791
792 protected:
793 Env::IOPriority io_priority_;
794 Env::WriteLifeTimeHint write_hint_;
795 };
796
797 // A file abstraction for random reading and writing.
798 class RandomRWFile {
799 public:
800 RandomRWFile() {}
801 virtual ~RandomRWFile() {}
802
803 // Indicates if the class makes use of direct I/O
804 // If false you must pass aligned buffer to Write()
805 virtual bool use_direct_io() const { return false; }
806
807 // Use the returned alignment value to allocate
808 // aligned buffer for Direct I/O
809 virtual size_t GetRequiredBufferAlignment() const { return kDefaultPageSize; }
810
811 // Write bytes in `data` at offset `offset`, Returns Status::OK() on success.
812 // Pass aligned buffer when use_direct_io() returns true.
813 virtual Status Write(uint64_t offset, const Slice& data) = 0;
814
815 // Read up to `n` bytes starting from offset `offset` and store them in
816 // result, provided `scratch` size should be at least `n`.
817 // Returns Status::OK() on success.
818 virtual Status Read(uint64_t offset, size_t n, Slice* result,
819 char* scratch) const = 0;
820
821 virtual Status Flush() = 0;
822
823 virtual Status Sync() = 0;
824
825 virtual Status Fsync() { return Sync(); }
826
827 virtual Status Close() = 0;
828
829 // If you're adding methods here, remember to add them to
830 // RandomRWFileWrapper too.
831
832 // No copying allowed
833 RandomRWFile(const RandomRWFile&) = delete;
834 RandomRWFile& operator=(const RandomRWFile&) = delete;
835 };
836
837 // MemoryMappedFileBuffer object represents a memory-mapped file's raw buffer.
838 // Subclasses should release the mapping upon destruction.
839 class MemoryMappedFileBuffer {
840 public:
841 MemoryMappedFileBuffer(void* _base, size_t _length)
842 : base_(_base), length_(_length) {}
843
844 virtual ~MemoryMappedFileBuffer() = 0;
845
846 // We do not want to unmap this twice. We can make this class
847 // movable if desired, however, since
848 MemoryMappedFileBuffer(const MemoryMappedFileBuffer&) = delete;
849 MemoryMappedFileBuffer& operator=(const MemoryMappedFileBuffer&) = delete;
850
851 void* GetBase() const { return base_; }
852 size_t GetLen() const { return length_; }
853
854 protected:
855 void* base_;
856 const size_t length_;
857 };
858
859 // Directory object represents collection of files and implements
860 // filesystem operations that can be executed on directories.
861 class Directory {
862 public:
863 virtual ~Directory() {}
864 // Fsync directory. Can be called concurrently from multiple threads.
865 virtual Status Fsync() = 0;
866
867 virtual size_t GetUniqueId(char* /*id*/, size_t /*max_size*/) const {
868 return 0;
869 }
870
871 // If you're adding methods here, remember to add them to
872 // DirectoryWrapper too.
873 };
874
875 enum InfoLogLevel : unsigned char {
876 DEBUG_LEVEL = 0,
877 INFO_LEVEL,
878 WARN_LEVEL,
879 ERROR_LEVEL,
880 FATAL_LEVEL,
881 HEADER_LEVEL,
882 NUM_INFO_LOG_LEVELS,
883 };
884
885 // An interface for writing log messages.
886 class Logger {
887 public:
888 size_t kDoNotSupportGetLogFileSize = (std::numeric_limits<size_t>::max)();
889
890 explicit Logger(const InfoLogLevel log_level = InfoLogLevel::INFO_LEVEL)
891 : closed_(false), log_level_(log_level) {}
892 virtual ~Logger();
893
894 // Close the log file. Must be called before destructor. If the return
895 // status is NotSupported(), it means the implementation does cleanup in
896 // the destructor
897 virtual Status Close();
898
899 // Write a header to the log file with the specified format
900 // It is recommended that you log all header information at the start of the
901 // application. But it is not enforced.
902 virtual void LogHeader(const char* format, va_list ap) {
903 // Default implementation does a simple INFO level log write.
904 // Please override as per the logger class requirement.
905 Logv(format, ap);
906 }
907
908 // Write an entry to the log file with the specified format.
909 virtual void Logv(const char* format, va_list ap) = 0;
910
911 // Write an entry to the log file with the specified log level
912 // and format. Any log with level under the internal log level
913 // of *this (see @SetInfoLogLevel and @GetInfoLogLevel) will not be
914 // printed.
915 virtual void Logv(const InfoLogLevel log_level, const char* format,
916 va_list ap);
917
918 virtual size_t GetLogFileSize() const { return kDoNotSupportGetLogFileSize; }
919 // Flush to the OS buffers
920 virtual void Flush() {}
921 virtual InfoLogLevel GetInfoLogLevel() const { return log_level_; }
922 virtual void SetInfoLogLevel(const InfoLogLevel log_level) {
923 log_level_ = log_level;
924 }
925
926 // If you're adding methods here, remember to add them to LoggerWrapper too.
927
928 protected:
929 virtual Status CloseImpl();
930 bool closed_;
931
932 private:
933 // No copying allowed
934 Logger(const Logger&);
935 void operator=(const Logger&);
936 InfoLogLevel log_level_;
937 };
938
939 // Identifies a locked file.
940 class FileLock {
941 public:
942 FileLock() {}
943 virtual ~FileLock();
944
945 private:
946 // No copying allowed
947 FileLock(const FileLock&);
948 void operator=(const FileLock&);
949 };
950
951 extern void LogFlush(const std::shared_ptr<Logger>& info_log);
952
953 extern void Log(const InfoLogLevel log_level,
954 const std::shared_ptr<Logger>& info_log, const char* format,
955 ...) ROCKSDB_PRINTF_FORMAT_ATTR(3, 4);
956
957 // a set of log functions with different log levels.
958 extern void Header(const std::shared_ptr<Logger>& info_log, const char* format,
959 ...) ROCKSDB_PRINTF_FORMAT_ATTR(2, 3);
960 extern void Debug(const std::shared_ptr<Logger>& info_log, const char* format,
961 ...) ROCKSDB_PRINTF_FORMAT_ATTR(2, 3);
962 extern void Info(const std::shared_ptr<Logger>& info_log, const char* format,
963 ...) ROCKSDB_PRINTF_FORMAT_ATTR(2, 3);
964 extern void Warn(const std::shared_ptr<Logger>& info_log, const char* format,
965 ...) ROCKSDB_PRINTF_FORMAT_ATTR(2, 3);
966 extern void Error(const std::shared_ptr<Logger>& info_log, const char* format,
967 ...) ROCKSDB_PRINTF_FORMAT_ATTR(2, 3);
968 extern void Fatal(const std::shared_ptr<Logger>& info_log, const char* format,
969 ...) ROCKSDB_PRINTF_FORMAT_ATTR(2, 3);
970
971 // Log the specified data to *info_log if info_log is non-nullptr.
972 // The default info log level is InfoLogLevel::INFO_LEVEL.
973 extern void Log(const std::shared_ptr<Logger>& info_log, const char* format,
974 ...) ROCKSDB_PRINTF_FORMAT_ATTR(2, 3);
975
976 extern void LogFlush(Logger* info_log);
977
978 extern void Log(const InfoLogLevel log_level, Logger* info_log,
979 const char* format, ...) ROCKSDB_PRINTF_FORMAT_ATTR(3, 4);
980
981 // The default info log level is InfoLogLevel::INFO_LEVEL.
982 extern void Log(Logger* info_log, const char* format, ...)
983 ROCKSDB_PRINTF_FORMAT_ATTR(2, 3);
984
985 // a set of log functions with different log levels.
986 extern void Header(Logger* info_log, const char* format, ...)
987 ROCKSDB_PRINTF_FORMAT_ATTR(2, 3);
988 extern void Debug(Logger* info_log, const char* format, ...)
989 ROCKSDB_PRINTF_FORMAT_ATTR(2, 3);
990 extern void Info(Logger* info_log, const char* format, ...)
991 ROCKSDB_PRINTF_FORMAT_ATTR(2, 3);
992 extern void Warn(Logger* info_log, const char* format, ...)
993 ROCKSDB_PRINTF_FORMAT_ATTR(2, 3);
994 extern void Error(Logger* info_log, const char* format, ...)
995 ROCKSDB_PRINTF_FORMAT_ATTR(2, 3);
996 extern void Fatal(Logger* info_log, const char* format, ...)
997 ROCKSDB_PRINTF_FORMAT_ATTR(2, 3);
998
999 // A utility routine: write "data" to the named file.
1000 extern Status WriteStringToFile(Env* env, const Slice& data,
1001 const std::string& fname,
1002 bool should_sync = false);
1003
1004 // A utility routine: read contents of named file into *data
1005 extern Status ReadFileToString(Env* env, const std::string& fname,
1006 std::string* data);
1007
1008 // Below are helpers for wrapping most of the classes in this file.
1009 // They forward all calls to another instance of the class.
1010 // Useful when wrapping the default implementations.
1011 // Typical usage is to inherit your wrapper from *Wrapper, e.g.:
1012 //
1013 // class MySequentialFileWrapper : public rocksdb::SequentialFileWrapper {
1014 // public:
1015 // MySequentialFileWrapper(rocksdb::SequentialFile* target):
1016 // rocksdb::SequentialFileWrapper(target) {}
1017 // Status Read(size_t n, Slice* result, char* scratch) override {
1018 // cout << "Doing a read of size " << n << "!" << endl;
1019 // return rocksdb::SequentialFileWrapper::Read(n, result, scratch);
1020 // }
1021 // // All other methods are forwarded to target_ automatically.
1022 // };
1023 //
1024 // This is often more convenient than inheriting the class directly because
1025 // (a) Don't have to override and forward all methods - the Wrapper will
1026 // forward everything you're not explicitly overriding.
1027 // (b) Don't need to update the wrapper when more methods are added to the
1028 // rocksdb class. Unless you actually want to override the behavior.
1029 // (And unless rocksdb people forgot to update the *Wrapper class.)
1030
1031 // An implementation of Env that forwards all calls to another Env.
1032 // May be useful to clients who wish to override just part of the
1033 // functionality of another Env.
1034 class EnvWrapper : public Env {
1035 public:
1036 // Initialize an EnvWrapper that delegates all calls to *t
1037 explicit EnvWrapper(Env* t) : target_(t) {}
1038 ~EnvWrapper() override;
1039
1040 // Return the target to which this Env forwards all calls
1041 Env* target() const { return target_; }
1042
1043 // The following text is boilerplate that forwards all methods to target()
1044 Status NewSequentialFile(const std::string& f,
1045 std::unique_ptr<SequentialFile>* r,
1046 const EnvOptions& options) override {
1047 return target_->NewSequentialFile(f, r, options);
1048 }
1049 Status NewRandomAccessFile(const std::string& f,
1050 std::unique_ptr<RandomAccessFile>* r,
1051 const EnvOptions& options) override {
1052 return target_->NewRandomAccessFile(f, r, options);
1053 }
1054 Status NewWritableFile(const std::string& f, std::unique_ptr<WritableFile>* r,
1055 const EnvOptions& options) override {
1056 return target_->NewWritableFile(f, r, options);
1057 }
1058 Status ReopenWritableFile(const std::string& fname,
1059 std::unique_ptr<WritableFile>* result,
1060 const EnvOptions& options) override {
1061 return target_->ReopenWritableFile(fname, result, options);
1062 }
1063 Status ReuseWritableFile(const std::string& fname,
1064 const std::string& old_fname,
1065 std::unique_ptr<WritableFile>* r,
1066 const EnvOptions& options) override {
1067 return target_->ReuseWritableFile(fname, old_fname, r, options);
1068 }
1069 Status NewRandomRWFile(const std::string& fname,
1070 std::unique_ptr<RandomRWFile>* result,
1071 const EnvOptions& options) override {
1072 return target_->NewRandomRWFile(fname, result, options);
1073 }
1074 Status NewMemoryMappedFileBuffer(
1075 const std::string& fname,
1076 std::unique_ptr<MemoryMappedFileBuffer>* result) override {
1077 return target_->NewMemoryMappedFileBuffer(fname, result);
1078 }
1079 Status NewDirectory(const std::string& name,
1080 std::unique_ptr<Directory>* result) override {
1081 return target_->NewDirectory(name, result);
1082 }
1083 Status FileExists(const std::string& f) override {
1084 return target_->FileExists(f);
1085 }
1086 Status GetChildren(const std::string& dir,
1087 std::vector<std::string>* r) override {
1088 return target_->GetChildren(dir, r);
1089 }
1090 Status GetChildrenFileAttributes(
1091 const std::string& dir, std::vector<FileAttributes>* result) override {
1092 return target_->GetChildrenFileAttributes(dir, result);
1093 }
1094 Status DeleteFile(const std::string& f) override {
1095 return target_->DeleteFile(f);
1096 }
1097 Status Truncate(const std::string& fname, size_t size) override {
1098 return target_->Truncate(fname, size);
1099 }
1100 Status CreateDir(const std::string& d) override {
1101 return target_->CreateDir(d);
1102 }
1103 Status CreateDirIfMissing(const std::string& d) override {
1104 return target_->CreateDirIfMissing(d);
1105 }
1106 Status DeleteDir(const std::string& d) override {
1107 return target_->DeleteDir(d);
1108 }
1109 Status GetFileSize(const std::string& f, uint64_t* s) override {
1110 return target_->GetFileSize(f, s);
1111 }
1112
1113 Status GetFileModificationTime(const std::string& fname,
1114 uint64_t* file_mtime) override {
1115 return target_->GetFileModificationTime(fname, file_mtime);
1116 }
1117
1118 Status RenameFile(const std::string& s, const std::string& t) override {
1119 return target_->RenameFile(s, t);
1120 }
1121
1122 Status LinkFile(const std::string& s, const std::string& t) override {
1123 return target_->LinkFile(s, t);
1124 }
1125
1126 Status NumFileLinks(const std::string& fname, uint64_t* count) override {
1127 return target_->NumFileLinks(fname, count);
1128 }
1129
1130 Status AreFilesSame(const std::string& first, const std::string& second,
1131 bool* res) override {
1132 return target_->AreFilesSame(first, second, res);
1133 }
1134
1135 Status LockFile(const std::string& f, FileLock** l) override {
1136 return target_->LockFile(f, l);
1137 }
1138
1139 Status UnlockFile(FileLock* l) override { return target_->UnlockFile(l); }
1140
1141 void Schedule(void (*f)(void* arg), void* a, Priority pri,
1142 void* tag = nullptr, void (*u)(void* arg) = nullptr) override {
1143 return target_->Schedule(f, a, pri, tag, u);
1144 }
1145
1146 int UnSchedule(void* tag, Priority pri) override {
1147 return target_->UnSchedule(tag, pri);
1148 }
1149
1150 void StartThread(void (*f)(void*), void* a) override {
1151 return target_->StartThread(f, a);
1152 }
1153 void WaitForJoin() override { return target_->WaitForJoin(); }
1154 unsigned int GetThreadPoolQueueLen(Priority pri = LOW) const override {
1155 return target_->GetThreadPoolQueueLen(pri);
1156 }
1157 Status GetTestDirectory(std::string* path) override {
1158 return target_->GetTestDirectory(path);
1159 }
1160 Status NewLogger(const std::string& fname,
1161 std::shared_ptr<Logger>* result) override {
1162 return target_->NewLogger(fname, result);
1163 }
1164 uint64_t NowMicros() override { return target_->NowMicros(); }
1165 uint64_t NowNanos() override { return target_->NowNanos(); }
1166 uint64_t NowCPUNanos() override { return target_->NowCPUNanos(); }
1167
1168 void SleepForMicroseconds(int micros) override {
1169 target_->SleepForMicroseconds(micros);
1170 }
1171 Status GetHostName(char* name, uint64_t len) override {
1172 return target_->GetHostName(name, len);
1173 }
1174 Status GetCurrentTime(int64_t* unix_time) override {
1175 return target_->GetCurrentTime(unix_time);
1176 }
1177 Status GetAbsolutePath(const std::string& db_path,
1178 std::string* output_path) override {
1179 return target_->GetAbsolutePath(db_path, output_path);
1180 }
1181 void SetBackgroundThreads(int num, Priority pri) override {
1182 return target_->SetBackgroundThreads(num, pri);
1183 }
1184 int GetBackgroundThreads(Priority pri) override {
1185 return target_->GetBackgroundThreads(pri);
1186 }
1187
1188 Status SetAllowNonOwnerAccess(bool allow_non_owner_access) override {
1189 return target_->SetAllowNonOwnerAccess(allow_non_owner_access);
1190 }
1191
1192 void IncBackgroundThreadsIfNeeded(int num, Priority pri) override {
1193 return target_->IncBackgroundThreadsIfNeeded(num, pri);
1194 }
1195
1196 void LowerThreadPoolIOPriority(Priority pool = LOW) override {
1197 target_->LowerThreadPoolIOPriority(pool);
1198 }
1199
1200 void LowerThreadPoolCPUPriority(Priority pool = LOW) override {
1201 target_->LowerThreadPoolCPUPriority(pool);
1202 }
1203
1204 std::string TimeToString(uint64_t time) override {
1205 return target_->TimeToString(time);
1206 }
1207
1208 Status GetThreadList(std::vector<ThreadStatus>* thread_list) override {
1209 return target_->GetThreadList(thread_list);
1210 }
1211
1212 ThreadStatusUpdater* GetThreadStatusUpdater() const override {
1213 return target_->GetThreadStatusUpdater();
1214 }
1215
1216 uint64_t GetThreadID() const override { return target_->GetThreadID(); }
1217
1218 std::string GenerateUniqueId() override {
1219 return target_->GenerateUniqueId();
1220 }
1221
1222 EnvOptions OptimizeForLogRead(const EnvOptions& env_options) const override {
1223 return target_->OptimizeForLogRead(env_options);
1224 }
1225 EnvOptions OptimizeForManifestRead(
1226 const EnvOptions& env_options) const override {
1227 return target_->OptimizeForManifestRead(env_options);
1228 }
1229 EnvOptions OptimizeForLogWrite(const EnvOptions& env_options,
1230 const DBOptions& db_options) const override {
1231 return target_->OptimizeForLogWrite(env_options, db_options);
1232 }
1233 EnvOptions OptimizeForManifestWrite(
1234 const EnvOptions& env_options) const override {
1235 return target_->OptimizeForManifestWrite(env_options);
1236 }
1237 EnvOptions OptimizeForCompactionTableWrite(
1238 const EnvOptions& env_options,
1239 const ImmutableDBOptions& immutable_ops) const override {
1240 return target_->OptimizeForCompactionTableWrite(env_options, immutable_ops);
1241 }
1242 EnvOptions OptimizeForCompactionTableRead(
1243 const EnvOptions& env_options,
1244 const ImmutableDBOptions& db_options) const override {
1245 return target_->OptimizeForCompactionTableRead(env_options, db_options);
1246 }
1247 Status GetFreeSpace(const std::string& path, uint64_t* diskfree) override {
1248 return target_->GetFreeSpace(path, diskfree);
1249 }
1250
1251 private:
1252 Env* target_;
1253 };
1254
1255 class SequentialFileWrapper : public SequentialFile {
1256 public:
1257 explicit SequentialFileWrapper(SequentialFile* target) : target_(target) {}
1258
1259 Status Read(size_t n, Slice* result, char* scratch) override {
1260 return target_->Read(n, result, scratch);
1261 }
1262 Status Skip(uint64_t n) override { return target_->Skip(n); }
1263 bool use_direct_io() const override { return target_->use_direct_io(); }
1264 size_t GetRequiredBufferAlignment() const override {
1265 return target_->GetRequiredBufferAlignment();
1266 }
1267 Status InvalidateCache(size_t offset, size_t length) override {
1268 return target_->InvalidateCache(offset, length);
1269 }
1270 Status PositionedRead(uint64_t offset, size_t n, Slice* result,
1271 char* scratch) override {
1272 return target_->PositionedRead(offset, n, result, scratch);
1273 }
1274
1275 private:
1276 SequentialFile* target_;
1277 };
1278
1279 class RandomAccessFileWrapper : public RandomAccessFile {
1280 public:
1281 explicit RandomAccessFileWrapper(RandomAccessFile* target)
1282 : target_(target) {}
1283
1284 Status Read(uint64_t offset, size_t n, Slice* result,
1285 char* scratch) const override {
1286 return target_->Read(offset, n, result, scratch);
1287 }
1288 Status Prefetch(uint64_t offset, size_t n) override {
1289 return target_->Prefetch(offset, n);
1290 }
1291 size_t GetUniqueId(char* id, size_t max_size) const override {
1292 return target_->GetUniqueId(id, max_size);
1293 };
1294 void Hint(AccessPattern pattern) override { target_->Hint(pattern); }
1295 bool use_direct_io() const override { return target_->use_direct_io(); }
1296 size_t GetRequiredBufferAlignment() const override {
1297 return target_->GetRequiredBufferAlignment();
1298 }
1299 Status InvalidateCache(size_t offset, size_t length) override {
1300 return target_->InvalidateCache(offset, length);
1301 }
1302
1303 private:
1304 RandomAccessFile* target_;
1305 };
1306
1307 class WritableFileWrapper : public WritableFile {
1308 public:
1309 explicit WritableFileWrapper(WritableFile* t) : target_(t) {}
1310
1311 Status Append(const Slice& data) override { return target_->Append(data); }
1312 Status PositionedAppend(const Slice& data, uint64_t offset) override {
1313 return target_->PositionedAppend(data, offset);
1314 }
1315 Status Truncate(uint64_t size) override { return target_->Truncate(size); }
1316 Status Close() override { return target_->Close(); }
1317 Status Flush() override { return target_->Flush(); }
1318 Status Sync() override { return target_->Sync(); }
1319 Status Fsync() override { return target_->Fsync(); }
1320 bool IsSyncThreadSafe() const override { return target_->IsSyncThreadSafe(); }
1321
1322 bool use_direct_io() const override { return target_->use_direct_io(); }
1323
1324 size_t GetRequiredBufferAlignment() const override {
1325 return target_->GetRequiredBufferAlignment();
1326 }
1327
1328 void SetIOPriority(Env::IOPriority pri) override {
1329 target_->SetIOPriority(pri);
1330 }
1331
1332 Env::IOPriority GetIOPriority() override { return target_->GetIOPriority(); }
1333
1334 void SetWriteLifeTimeHint(Env::WriteLifeTimeHint hint) override {
1335 target_->SetWriteLifeTimeHint(hint);
1336 }
1337
1338 Env::WriteLifeTimeHint GetWriteLifeTimeHint() override {
1339 return target_->GetWriteLifeTimeHint();
1340 }
1341
1342 uint64_t GetFileSize() override { return target_->GetFileSize(); }
1343
1344 void SetPreallocationBlockSize(size_t size) override {
1345 target_->SetPreallocationBlockSize(size);
1346 }
1347
1348 void GetPreallocationStatus(size_t* block_size,
1349 size_t* last_allocated_block) override {
1350 target_->GetPreallocationStatus(block_size, last_allocated_block);
1351 }
1352
1353 size_t GetUniqueId(char* id, size_t max_size) const override {
1354 return target_->GetUniqueId(id, max_size);
1355 }
1356
1357 Status InvalidateCache(size_t offset, size_t length) override {
1358 return target_->InvalidateCache(offset, length);
1359 }
1360
1361 Status RangeSync(uint64_t offset, uint64_t nbytes) override {
1362 return target_->RangeSync(offset, nbytes);
1363 }
1364
1365 void PrepareWrite(size_t offset, size_t len) override {
1366 target_->PrepareWrite(offset, len);
1367 }
1368
1369 Status Allocate(uint64_t offset, uint64_t len) override {
1370 return target_->Allocate(offset, len);
1371 }
1372
1373 private:
1374 WritableFile* target_;
1375 };
1376
1377 class RandomRWFileWrapper : public RandomRWFile {
1378 public:
1379 explicit RandomRWFileWrapper(RandomRWFile* target) : target_(target) {}
1380
1381 bool use_direct_io() const override { return target_->use_direct_io(); }
1382 size_t GetRequiredBufferAlignment() const override {
1383 return target_->GetRequiredBufferAlignment();
1384 }
1385 Status Write(uint64_t offset, const Slice& data) override {
1386 return target_->Write(offset, data);
1387 }
1388 Status Read(uint64_t offset, size_t n, Slice* result,
1389 char* scratch) const override {
1390 return target_->Read(offset, n, result, scratch);
1391 }
1392 Status Flush() override { return target_->Flush(); }
1393 Status Sync() override { return target_->Sync(); }
1394 Status Fsync() override { return target_->Fsync(); }
1395 Status Close() override { return target_->Close(); }
1396
1397 private:
1398 RandomRWFile* target_;
1399 };
1400
1401 class DirectoryWrapper : public Directory {
1402 public:
1403 explicit DirectoryWrapper(Directory* target) : target_(target) {}
1404
1405 Status Fsync() override { return target_->Fsync(); }
1406 size_t GetUniqueId(char* id, size_t max_size) const override {
1407 return target_->GetUniqueId(id, max_size);
1408 }
1409
1410 private:
1411 Directory* target_;
1412 };
1413
1414 class LoggerWrapper : public Logger {
1415 public:
1416 explicit LoggerWrapper(Logger* target) : target_(target) {}
1417
1418 Status Close() override { return target_->Close(); }
1419 void LogHeader(const char* format, va_list ap) override {
1420 return target_->LogHeader(format, ap);
1421 }
1422 void Logv(const char* format, va_list ap) override {
1423 return target_->Logv(format, ap);
1424 }
1425 void Logv(const InfoLogLevel log_level, const char* format,
1426 va_list ap) override {
1427 return target_->Logv(log_level, format, ap);
1428 }
1429 size_t GetLogFileSize() const override { return target_->GetLogFileSize(); }
1430 void Flush() override { return target_->Flush(); }
1431 InfoLogLevel GetInfoLogLevel() const override {
1432 return target_->GetInfoLogLevel();
1433 }
1434 void SetInfoLogLevel(const InfoLogLevel log_level) override {
1435 return target_->SetInfoLogLevel(log_level);
1436 }
1437
1438 private:
1439 Logger* target_;
1440 };
1441
1442 // Returns a new environment that stores its data in memory and delegates
1443 // all non-file-storage tasks to base_env. The caller must delete the result
1444 // when it is no longer needed.
1445 // *base_env must remain live while the result is in use.
1446 Env* NewMemEnv(Env* base_env);
1447
1448 // Returns a new environment that is used for HDFS environment.
1449 // This is a factory method for HdfsEnv declared in hdfs/env_hdfs.h
1450 Status NewHdfsEnv(Env** hdfs_env, const std::string& fsname);
1451
1452 // Returns a new environment that measures function call times for filesystem
1453 // operations, reporting results to variables in PerfContext.
1454 // This is a factory method for TimedEnv defined in utilities/env_timed.cc.
1455 Env* NewTimedEnv(Env* base_env);
1456
1457 } // namespace rocksdb