/Users/deen/code/yugabyte-db/src/yb/util/file_system.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | |
14 | | #ifndef YB_UTIL_FILE_SYSTEM_H |
15 | | #define YB_UTIL_FILE_SYSTEM_H |
16 | | |
17 | | #include <string> |
18 | | |
19 | | #include "yb/util/coding_consts.h" |
20 | | #include "yb/util/slice.h" |
21 | | #include "yb/util/status_fwd.h" |
22 | | |
23 | | namespace yb { |
24 | | |
25 | | // Options for opening a file to read/write. |
26 | | struct FileSystemOptions { |
27 | | |
28 | 4.00M | FileSystemOptions() {} |
29 | | |
30 | | static const FileSystemOptions kDefault; |
31 | | |
32 | | // If true, then allow caching of data in OS buffers. |
33 | | bool use_os_buffer = true; |
34 | | |
35 | | // If true, then use mmap to read data. |
36 | | bool use_mmap_reads = false; |
37 | | }; |
38 | | |
39 | | // Interface to filesystem. |
40 | | class FileSystem { |
41 | | public: |
42 | | }; |
43 | | |
44 | | // A file abstraction for reading sequentially through a file. |
45 | | class SequentialFile { |
46 | | public: |
47 | 1.72M | SequentialFile() {} |
48 | 1.72M | virtual ~SequentialFile() {} |
49 | | |
50 | | // Read up to "n" bytes from the file. "scratch[0..n-1]" may be |
51 | | // written by this routine. Sets "*result" to the data that was |
52 | | // read (including if fewer than "n" bytes were successfully read). |
53 | | // May set "*result" to point at data in "scratch[0..n-1]", so |
54 | | // "scratch[0..n-1]" must be live when "*result" is used. |
55 | | // If an error was encountered, returns a non-OK status. |
56 | | // |
57 | | // REQUIRES: External synchronization |
58 | | virtual CHECKED_STATUS Read(size_t n, Slice* result, uint8_t* scratch) = 0; |
59 | | |
60 | | // Skip "n" bytes from the file. This is guaranteed to be no |
61 | | // slower that reading the same data, but may be faster. |
62 | | // |
63 | | // If end of file is reached, skipping will stop at the end of the |
64 | | // file, and Skip will return OK. |
65 | | // |
66 | | // REQUIRES: External synchronization |
67 | | virtual CHECKED_STATUS Skip(uint64_t n) = 0; |
68 | | |
69 | | // Remove any kind of caching of data from the offset to offset+length |
70 | | // of this file. If the length is 0, then it refers to the end of file. |
71 | | // If the system is not caching the file contents, then this is a noop. |
72 | | virtual CHECKED_STATUS InvalidateCache(size_t offset, size_t length); |
73 | | |
74 | | // Returns the filename provided when the SequentialFile was constructed. |
75 | | virtual const std::string& filename() const = 0; |
76 | | }; |
77 | | |
78 | | class FileWithUniqueId { |
79 | | public: |
80 | | static constexpr const auto kPosixFileUniqueIdMaxSize = kMaxVarint64Length * 3; |
81 | 5.32M | virtual ~FileWithUniqueId() {} |
82 | | |
83 | | // Tries to get an unique ID for this file that will be the same each time |
84 | | // the file is opened (and will stay the same while the file is open). |
85 | | // id should have at least capacity of kPosixFileUniqueIdMaxSize to hold the result. |
86 | | // |
87 | | // This function guarantees, for IDs from a given environment, two unique ids |
88 | | // cannot be made equal to each other by adding arbitrary bytes to one of |
89 | | // them. That is, no unique ID is the prefix of another. |
90 | | // |
91 | | // This function guarantees that the returned ID will not be interpretable as |
92 | | // a single varint. |
93 | | // |
94 | | // Note: these IDs are only valid for the duration of the process. |
95 | | virtual size_t GetUniqueId(char *id) const = 0; |
96 | | }; |
97 | | |
98 | | // An interface for a function that validates a sequence of bytes we've just read. Could be used |
99 | | // e.g. for checksum validation. We are not using boost::function for efficiency, because this |
100 | | // validation happens on the critical read of read requests. |
101 | | class ReadValidator { |
102 | | public: |
103 | | virtual CHECKED_STATUS Validate(const Slice& s) const = 0; |
104 | 3.98M | virtual ~ReadValidator() = default; |
105 | | }; |
106 | | |
107 | | // A file abstraction for randomly reading the contents of a file. |
108 | | class RandomAccessFile : public FileWithUniqueId { |
109 | | public: |
110 | 2.27M | RandomAccessFile() { } |
111 | | virtual ~RandomAccessFile(); |
112 | | |
113 | | // Read up to "n" bytes from the file starting at "offset". |
114 | | // "scratch[0..n-1]" may be written by this routine. Sets "*result" |
115 | | // to the data that was read (including if fewer than "n" bytes were |
116 | | // successfully read). May set "*result" to point at data in |
117 | | // "scratch[0..n-1]", so "scratch[0..n-1]" must be live when |
118 | | // "*result" is used. If an error was encountered, returns a non-OK |
119 | | // status. |
120 | | // |
121 | | // Safe for concurrent use by multiple threads. |
122 | | virtual CHECKED_STATUS Read(uint64_t offset, size_t n, Slice* result, |
123 | | uint8_t *scratch) const = 0; |
124 | | |
125 | | // Similar to Read, but uses the given callback to validate the result. |
126 | | virtual CHECKED_STATUS ReadAndValidate( |
127 | | uint64_t offset, size_t n, Slice* result, char* scratch, const ReadValidator& validator); |
128 | | |
129 | | CHECKED_STATUS Read(uint64_t offset, size_t n, Slice* result, char* scratch); |
130 | | |
131 | | // Returns the size of the file |
132 | | virtual Result<uint64_t> Size() const = 0; |
133 | | |
134 | | virtual Result<uint64_t> INode() const = 0; |
135 | | |
136 | | // Returns the filename provided when the RandomAccessFile was constructed. |
137 | | virtual const std::string& filename() const = 0; |
138 | | |
139 | | // Returns the approximate memory usage of this RandomAccessFile including |
140 | | // the object itself. |
141 | | virtual size_t memory_footprint() const = 0; |
142 | | |
143 | 133k | virtual bool IsEncrypted() const { |
144 | 133k | return false; |
145 | 133k | } |
146 | | |
147 | 27.5k | virtual uint64_t GetEncryptionHeaderSize() const { |
148 | 27.5k | return 0; |
149 | 27.5k | } |
150 | | |
151 | | // Used by the file_reader_writer to decide if the ReadAhead wrapper |
152 | | // should simply forward the call and do not enact buffering or locking. |
153 | 922 | virtual bool ShouldForwardRawRequest() const { |
154 | 922 | return false; |
155 | 922 | } |
156 | | |
157 | | // For cases when read-ahead is implemented in the platform dependent layer. |
158 | 0 | virtual void EnableReadAhead() {} |
159 | | |
160 | | // For documentation, refer to FileWithUniqueId::GetUniqueId() |
161 | 139k | virtual size_t GetUniqueId(char* id) const override { |
162 | 139k | return 0; // Default implementation to prevent issues with backwards compatibility. |
163 | 139k | } |
164 | | |
165 | | enum AccessPattern { NORMAL, RANDOM, SEQUENTIAL, WILLNEED, DONTNEED }; |
166 | | |
167 | 22.9k | virtual void Hint(AccessPattern pattern) {} |
168 | | |
169 | | // Remove any kind of caching of data from the offset to offset+length |
170 | | // of this file. If the length is 0, then it refers to the end of file. |
171 | | // If the system is not caching the file contents, then this is a noop. |
172 | | virtual CHECKED_STATUS InvalidateCache(size_t offset, size_t length); |
173 | | }; |
174 | | |
175 | | class SequentialFileWrapper : public SequentialFile { |
176 | | public: |
177 | 18 | explicit SequentialFileWrapper(std::unique_ptr<SequentialFile> t) : target_(std::move(t)) {} |
178 | | |
179 | | Status Read(size_t n, Slice* result, uint8_t* scratch) override; |
180 | | |
181 | | Status Skip(uint64_t n) override; |
182 | | |
183 | | Status InvalidateCache(size_t offset, size_t length) override; |
184 | | |
185 | 0 | const std::string& filename() const override { return target_->filename(); } |
186 | | |
187 | | private: |
188 | | std::unique_ptr<SequentialFile> target_; |
189 | | }; |
190 | | |
191 | | class RandomAccessFileWrapper : public RandomAccessFile { |
192 | | public: |
193 | 1.00k | explicit RandomAccessFileWrapper(std::unique_ptr<RandomAccessFile> t) : target_(std::move(t)) {} |
194 | | |
195 | | // Return the target to which this RandomAccessFile forwards all calls. |
196 | 0 | RandomAccessFile* target() const { return target_.get(); } |
197 | | |
198 | | CHECKED_STATUS Read(uint64_t offset, size_t n, Slice* result, uint8_t* scratch) const override; |
199 | | |
200 | | Result<uint64_t> Size() const override; |
201 | | |
202 | | Result<uint64_t> INode() const override; |
203 | | |
204 | 24 | const std::string& filename() const override { return target_->filename(); } |
205 | | |
206 | 0 | size_t memory_footprint() const override { return target_->memory_footprint(); } |
207 | | |
208 | 496 | bool IsEncrypted() const override { return target_->IsEncrypted(); } |
209 | | |
210 | 0 | uint64_t GetEncryptionHeaderSize() const override { return target_->GetEncryptionHeaderSize(); } |
211 | | |
212 | 922 | bool ShouldForwardRawRequest() const override { |
213 | 922 | return target_->ShouldForwardRawRequest(); |
214 | 922 | } |
215 | | |
216 | 0 | void EnableReadAhead() override { return target_->EnableReadAhead(); } |
217 | | |
218 | 936 | size_t GetUniqueId(char* id) const override { |
219 | 936 | return target_->GetUniqueId(id); |
220 | 936 | } |
221 | | |
222 | 1.00k | void Hint(AccessPattern pattern) override { return target_->Hint(pattern); } |
223 | | |
224 | | Status InvalidateCache(size_t offset, size_t length) override; |
225 | | |
226 | | private: |
227 | | std::unique_ptr<RandomAccessFile> target_; |
228 | | }; |
229 | | |
230 | | |
231 | | } // namespace yb |
232 | | |
233 | | #endif // YB_UTIL_FILE_SYSTEM_H |