/Users/deen/code/yugabyte-db/src/yb/rocksdb/db/version_edit.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
2 | | // This source code is licensed under the BSD-style license found in the |
3 | | // LICENSE file in the root directory of this source tree. An additional grant |
4 | | // of patent rights can be found in the PATENTS file in the same directory. |
5 | | // |
6 | | // The following only applies to changes made to this file as part of YugaByte development. |
7 | | // |
8 | | // Portions Copyright (c) YugaByte, Inc. |
9 | | // |
10 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
11 | | // in compliance with the License. You may obtain a copy of the License at |
12 | | // |
13 | | // http://www.apache.org/licenses/LICENSE-2.0 |
14 | | // |
15 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
16 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
17 | | // or implied. See the License for the specific language governing permissions and limitations |
18 | | // under the License. |
19 | | // |
20 | | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. |
21 | | // Use of this source code is governed by a BSD-style license that can be |
22 | | // found in the LICENSE file. See the AUTHORS file for names of contributors. |
23 | | |
24 | | #ifndef YB_ROCKSDB_DB_VERSION_EDIT_H |
25 | | #define YB_ROCKSDB_DB_VERSION_EDIT_H |
26 | | |
27 | | #include <stddef.h> |
28 | | #include <stdint.h> |
29 | | #include <stdio.h> |
30 | | #include <string.h> |
31 | | |
32 | | #include <algorithm> |
33 | | #include <limits> |
34 | | #include <memory> |
35 | | #include <set> |
36 | | #include <stack> |
37 | | #include <string> |
38 | | #include <unordered_map> |
39 | | #include <utility> |
40 | | #include <vector> |
41 | | |
42 | | #include <boost/optional.hpp> |
43 | | |
44 | | #include "yb/gutil/atomicops.h" |
45 | | |
46 | | #include "yb/rocksdb/cache.h" |
47 | | #include "yb/rocksdb/db/dbformat.h" |
48 | | #include "yb/rocksdb/listener.h" |
49 | | #include "yb/rocksdb/options.h" |
50 | | #include "yb/rocksdb/status.h" |
51 | | #include "yb/rocksdb/types.h" |
52 | | |
53 | | namespace rocksdb { |
54 | | |
55 | | class TableCache; |
56 | | class VersionSet; |
57 | | class VersionEditPB; |
58 | | |
59 | | const uint64_t kFileNumberMask = 0x3FFFFFFFFFFFFFFF; |
60 | | |
61 | | extern uint64_t PackFileNumberAndPathId(uint64_t number, uint64_t path_id); |
62 | | |
63 | | // A copyable structure contains information needed to read data from an SST |
64 | | // file. It can contains a pointer to a table reader opened for the file, or |
65 | | // file number and size, which can be used to create a new table reader for it. |
66 | | // The behavior is undefined when a copied of the structure is used when the |
67 | | // file is not in any live version any more. |
68 | | // SST can be either one file containing both meta data and data or it can be split into |
69 | | // multiple files: one metadata file and number of data files (S-Blocks aka storage-blocks). |
70 | | // As of 2017-03-10 there is at most one data file. |
71 | | // Base file is a file which contains SST metadata. So, if SST is either one base file, or |
72 | | // in case SST is split into multiple files, base file is a metadata file. |
73 | | struct FileDescriptor { |
74 | | // Table reader in table_reader_handle |
75 | | TableReader* table_reader; |
76 | | uint64_t packed_number_and_path_id; |
77 | | uint64_t total_file_size; // total file(s) size in bytes |
78 | | uint64_t base_file_size; // base file size in bytes |
79 | | |
80 | 282k | FileDescriptor() : FileDescriptor(0, 0, 0, 0) {} Unexecuted instantiation: rocksdb::FileDescriptor::FileDescriptor() rocksdb::FileDescriptor::FileDescriptor() Line | Count | Source | 80 | 282k | FileDescriptor() : FileDescriptor(0, 0, 0, 0) {} |
|
81 | | |
82 | | FileDescriptor(uint64_t number, uint32_t path_id, uint64_t _total_file_size, |
83 | | uint64_t _base_file_size) |
84 | | : table_reader(nullptr), |
85 | | packed_number_and_path_id(PackFileNumberAndPathId(number, path_id)), |
86 | | total_file_size(_total_file_size), |
87 | 418k | base_file_size(_base_file_size) {} |
88 | | |
89 | 35.3M | uint64_t GetNumber() const { |
90 | 35.3M | return packed_number_and_path_id & kFileNumberMask; |
91 | 35.3M | } |
92 | 907k | uint32_t GetPathId() const { |
93 | 907k | return static_cast<uint32_t>( |
94 | 907k | packed_number_and_path_id / (kFileNumberMask + 1)); |
95 | 907k | } |
96 | 3.09M | uint64_t GetTotalFileSize() const { return total_file_size; } |
97 | 637k | uint64_t GetBaseFileSize() const { return base_file_size; } |
98 | | |
99 | | std::string ToString() const; |
100 | | }; |
101 | | |
102 | | YB_DEFINE_ENUM(UpdateBoundariesType, (kAll)(kSmallest)(kLargest)); |
103 | | |
104 | | struct FileMetaData { |
105 | | typedef FileBoundaryValues<InternalKey> BoundaryValues; |
106 | | |
107 | | int refs; |
108 | | FileDescriptor fd; |
109 | | bool being_compacted; // Is this file undergoing compaction? |
110 | | bool being_deleted = false; // Updated by DB::DeleteFile |
111 | | BoundaryValues smallest; // The smallest values in this file |
112 | | BoundaryValues largest; // The largest values in this file |
113 | | bool imported = false; // Was this file imported from another DB. |
114 | | |
115 | | // Needs to be disposed when refs becomes 0. |
116 | | Cache::Handle* table_reader_handle; |
117 | | |
118 | | // Stats for compensating deletion entries during compaction |
119 | | |
120 | | // File size compensated by deletion entry. |
121 | | // This is updated in Version::UpdateAccumulatedStats() first time when the |
122 | | // file is created or loaded. After it is updated (!= 0), it is immutable. |
123 | | uint64_t compensated_file_size; |
124 | | // These values can mutate, but they can only be read or written from |
125 | | // single-threaded LogAndApply thread |
126 | | uint64_t num_entries; // the number of entries. |
127 | | uint64_t num_deletions; // the number of deletion entries. |
128 | | uint64_t raw_key_size; // total uncompressed key size. |
129 | | uint64_t raw_value_size; // total uncompressed value size. |
130 | | bool init_stats_from_file; // true if the data-entry stats of this file |
131 | | // has initialized from file. |
132 | | |
133 | | bool marked_for_compaction; // True if client asked us nicely to compact this |
134 | | // file. |
135 | | |
136 | 28.7k | bool delete_after_compaction() const { |
137 | 28.7k | return base::subtle::NoBarrier_Load(&delete_after_compaction_) != 0; |
138 | 28.7k | } |
139 | | |
140 | 55 | void set_delete_after_compaction(bool value) { |
141 | 55 | base::subtle::Release_Store(&delete_after_compaction_, value ? 1 : 00 ); |
142 | 55 | } |
143 | | |
144 | | FileMetaData(); |
145 | | |
146 | | // REQUIRED: Keys must be given to the function in sorted order (it expects |
147 | | // the last key to be the largest). |
148 | | void UpdateBoundaries(InternalKey key, const FileBoundaryValuesBase& source); |
149 | | |
150 | | // Update all boundaries except key. |
151 | | void UpdateBoundariesExceptKey(const FileBoundaryValuesBase& source, UpdateBoundariesType type); |
152 | | |
153 | | bool Unref(TableCache* table_cache); |
154 | | |
155 | | Slice UserFilter() const; // Extracts user filter from largest boundary value if present. |
156 | | |
157 | | // Outputs smallest and largest user frontiers to string, if they exist. |
158 | | std::string FrontiersToString() const; |
159 | | |
160 | | std::string ToString() const; |
161 | | |
162 | | private: |
163 | | // True if file has been marked for direct deletion. |
164 | | // We cannot use std::atomic<bool> here, because this class is stored in std::vector. |
165 | | AtomicWord delete_after_compaction_ = 0; |
166 | | }; |
167 | | |
168 | | class VersionEdit { |
169 | | public: |
170 | 2.64M | VersionEdit() { Clear(); } |
171 | 2.62M | ~VersionEdit() { } |
172 | | |
173 | | void Clear(); |
174 | | |
175 | 282k | void SetComparatorName(const Slice& name) { |
176 | 282k | comparator_ = name.ToString(); |
177 | 282k | } |
178 | 321k | void SetLogNumber(uint64_t num) { |
179 | 321k | log_number_ = num; |
180 | 321k | } |
181 | 333k | void SetPrevLogNumber(uint64_t num) { |
182 | 333k | prev_log_number_ = num; |
183 | 333k | } |
184 | 611k | void SetNextFile(uint64_t num) { |
185 | 611k | next_file_number_ = num; |
186 | 611k | } |
187 | 760k | void SetLastSequence(SequenceNumber seq) { |
188 | 760k | last_sequence_ = seq; |
189 | 760k | } |
190 | | void UpdateFlushedFrontier(UserFrontierPtr value); |
191 | | void ModifyFlushedFrontier(UserFrontierPtr value, FrontierModificationMode mode); |
192 | 4.26k | void SetMaxColumnFamily(uint32_t max_column_family) { |
193 | 4.26k | max_column_family_ = max_column_family; |
194 | 4.26k | } |
195 | | |
196 | | void InitNewDB(); |
197 | | |
198 | | // Add the specified file at the specified number. |
199 | | // REQUIRES: This version has not been saved (see VersionSet::SaveTo) |
200 | | // REQUIRES: "smallest" and "largest" are smallest and largest keys in file |
201 | | void AddTestFile(int level, |
202 | | const FileDescriptor& fd, |
203 | | const FileMetaData::BoundaryValues& smallest, |
204 | | const FileMetaData::BoundaryValues& largest, |
205 | | bool marked_for_compaction); |
206 | | |
207 | | void AddFile(int level, const FileMetaData& f); |
208 | | |
209 | | void AddCleanedFile(int level, const FileMetaData& f); |
210 | | |
211 | | // Delete the specified "file" from the specified "level". |
212 | 65.3k | void DeleteFile(int level, uint64_t file) { |
213 | 65.3k | deleted_files_.insert({level, file}); |
214 | 65.3k | } |
215 | | |
216 | | // Number of edits |
217 | 443k | size_t NumEntries() { return new_files_.size() + deleted_files_.size(); } |
218 | | |
219 | 1.67M | bool IsColumnFamilyAdd() { |
220 | 1.67M | return column_family_name_ ? true6.86k : false1.66M ; |
221 | 1.67M | } |
222 | | |
223 | 1.67M | bool IsColumnFamilyManipulation() { |
224 | 1.67M | return IsColumnFamilyAdd() || is_column_family_drop_1.66M ; |
225 | 1.67M | } |
226 | | |
227 | 795k | void SetColumnFamily(uint32_t column_family_id) { |
228 | 795k | column_family_ = column_family_id; |
229 | 795k | } |
230 | | |
231 | | // set column family ID by calling SetColumnFamily() |
232 | 442k | void AddColumnFamily(const std::string& name) { |
233 | 442k | DCHECK(!is_column_family_drop_); |
234 | 442k | DCHECK(!column_family_name_); |
235 | 442k | DCHECK_EQ(NumEntries(), 0); |
236 | 442k | column_family_name_ = name; |
237 | 442k | } |
238 | | |
239 | | // set column family ID by calling SetColumnFamily() |
240 | 27 | void DropColumnFamily() { |
241 | 27 | DCHECK(!is_column_family_drop_); |
242 | 27 | DCHECK(!column_family_name_); |
243 | 27 | DCHECK_EQ(NumEntries(), 0); |
244 | 27 | is_column_family_drop_ = true; |
245 | 27 | } |
246 | | |
247 | | // return true on success. |
248 | | bool AppendEncodedTo(std::string* dst) const; |
249 | | Status DecodeFrom(BoundaryValuesExtractor* extractor, const Slice& src); |
250 | | |
251 | | typedef std::set<std::pair<int, uint64_t>> DeletedFileSet; |
252 | | |
253 | 808k | const DeletedFileSet& GetDeletedFiles() { return deleted_files_; } |
254 | 809k | const std::vector<std::pair<int, FileMetaData>>& GetNewFiles() { |
255 | 809k | return new_files_; |
256 | 809k | } |
257 | | |
258 | | std::string DebugString(bool hex_key = false) const; |
259 | | |
260 | 0 | std::string ToString() const { |
261 | 0 | return DebugString(); |
262 | 0 | } |
263 | | |
264 | | private: |
265 | | friend class VersionSet; |
266 | | friend class Version; |
267 | | |
268 | | bool EncodeTo(VersionEditPB* out) const; |
269 | | |
270 | | int max_level_; |
271 | | boost::optional<std::string> comparator_; |
272 | | boost::optional<uint64_t> log_number_; |
273 | | boost::optional<uint64_t> prev_log_number_; |
274 | | boost::optional<uint64_t> next_file_number_; |
275 | | boost::optional<uint32_t> max_column_family_; |
276 | | boost::optional<SequenceNumber> last_sequence_; |
277 | | UserFrontierPtr flushed_frontier_; |
278 | | |
279 | | // Used when we're resetting the flushed frontier to a potentially lower value. This is needed |
280 | | // when restoring from a backup into a new Raft group with an unrelated sequence of OpIds. |
281 | | bool force_flushed_frontier_ = false; |
282 | | |
283 | | DeletedFileSet deleted_files_; |
284 | | std::vector<std::pair<int, FileMetaData>> new_files_; |
285 | | |
286 | | // Each version edit record should have column_family_id set |
287 | | // If it's not set, it is default (0) |
288 | | uint32_t column_family_; |
289 | | // a version edit can be either column_family add or |
290 | | // column_family drop. If it's column family add, |
291 | | // it also includes column family name. |
292 | | bool is_column_family_drop_; |
293 | | boost::optional<std::string> column_family_name_; |
294 | | }; |
295 | | |
296 | | } // namespace rocksdb |
297 | | |
298 | | #endif // YB_ROCKSDB_DB_VERSION_EDIT_H |