YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/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