]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/db/compaction/compaction_picker.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / db / compaction / compaction_picker.h
CommitLineData
7c673cae 1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
11fdf7f2
TL
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).
7c673cae
FG
5//
6// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7// Use of this source code is governed by a BSD-style license that can be
8// found in the LICENSE file. See the AUTHORS file for names of contributors.
9
10#pragma once
11
12#include <memory>
13#include <set>
14#include <string>
15#include <unordered_set>
16#include <vector>
17
f67539c2 18#include "db/compaction/compaction.h"
7c673cae
FG
19#include "db/version_set.h"
20#include "options/cf_options.h"
21#include "rocksdb/env.h"
22#include "rocksdb/options.h"
23#include "rocksdb/status.h"
24
f67539c2
TL
25namespace ROCKSDB_NAMESPACE {
26
27// The file contains an abstract class CompactionPicker, and its two
28// sub-classes LevelCompactionPicker and NullCompactionPicker, as
29// well as some helper functions used by them.
7c673cae
FG
30
31class LogBuffer;
32class Compaction;
33class VersionStorageInfo;
34struct CompactionInputFiles;
35
f67539c2
TL
36// An abstract class to pick compactions from an existing LSM-tree.
37//
38// Each compaction style inherits the class and implement the
39// interface to form automatic compactions. If NeedCompaction() is true,
40// then call PickCompaction() to find what files need to be compacted
41// and where to put the output files.
42//
43// Non-virtual functions CompactRange() and CompactFiles() are used to
44// pick files to compact based on users' DB::CompactRange() and
45// DB::CompactFiles() requests, respectively. There is little
46// compaction style specific logic for them.
7c673cae
FG
47class CompactionPicker {
48 public:
1e59de90 49 CompactionPicker(const ImmutableOptions& ioptions,
7c673cae
FG
50 const InternalKeyComparator* icmp);
51 virtual ~CompactionPicker();
52
53 // Pick level and inputs for a new compaction.
54 // Returns nullptr if there is no compaction to be done.
55 // Otherwise returns a pointer to a heap-allocated object that
56 // describes the compaction. Caller should delete the result.
f67539c2
TL
57 virtual Compaction* PickCompaction(
58 const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
20effc67
TL
59 const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
60 LogBuffer* log_buffer,
f67539c2 61 SequenceNumber earliest_memtable_seqno = kMaxSequenceNumber) = 0;
7c673cae
FG
62
63 // Return a compaction object for compacting the range [begin,end] in
64 // the specified level. Returns nullptr if there is nothing in that
65 // level that overlaps the specified range. Caller should delete
66 // the result.
67 //
68 // The returned Compaction might not include the whole requested range.
69 // In that case, compaction_end will be set to the next key that needs
70 // compacting. In case the compaction will compact the whole range,
71 // compaction_end will be set to nullptr.
72 // Client is responsible for compaction_end storage -- when called,
73 // *compaction_end should point to valid InternalKey!
74 virtual Compaction* CompactRange(
75 const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
20effc67
TL
76 const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
77 int input_level, int output_level,
f67539c2 78 const CompactRangeOptions& compact_range_options,
11fdf7f2 79 const InternalKey* begin, const InternalKey* end,
f67539c2 80 InternalKey** compaction_end, bool* manual_conflict,
1e59de90 81 uint64_t max_file_num_to_ignore, const std::string& trim_ts);
7c673cae
FG
82
83 // The maximum allowed output level. Default value is NumberLevels() - 1.
84 virtual int MaxOutputLevel() const { return NumberLevels() - 1; }
85
86 virtual bool NeedsCompaction(const VersionStorageInfo* vstorage) const = 0;
87
88// Sanitize the input set of compaction input files.
89// When the input parameters do not describe a valid compaction, the
90// function will try to fix the input_files by adding necessary
91// files. If it's not possible to conver an invalid input_files
92// into a valid one by adding more files, the function will return a
93// non-ok status with specific reason.
94#ifndef ROCKSDB_LITE
95 Status SanitizeCompactionInputFiles(std::unordered_set<uint64_t>* input_files,
96 const ColumnFamilyMetaData& cf_meta,
97 const int output_level) const;
98#endif // ROCKSDB_LITE
99
100 // Free up the files that participated in a compaction
101 //
102 // Requirement: DB mutex held
103 void ReleaseCompactionFiles(Compaction* c, Status status);
104
105 // Returns true if any one of the specified files are being compacted
106 bool AreFilesInCompaction(const std::vector<FileMetaData*>& files);
107
108 // Takes a list of CompactionInputFiles and returns a (manual) Compaction
109 // object.
11fdf7f2
TL
110 //
111 // Caller must provide a set of input files that has been passed through
112 // `SanitizeCompactionInputFiles` earlier. The lock should not be released
113 // between that call and this one.
7c673cae
FG
114 Compaction* CompactFiles(const CompactionOptions& compact_options,
115 const std::vector<CompactionInputFiles>& input_files,
116 int output_level, VersionStorageInfo* vstorage,
117 const MutableCFOptions& mutable_cf_options,
20effc67 118 const MutableDBOptions& mutable_db_options,
7c673cae
FG
119 uint32_t output_path_id);
120
121 // Converts a set of compaction input file numbers into
122 // a list of CompactionInputFiles.
123 Status GetCompactionInputsFromFileNumbers(
124 std::vector<CompactionInputFiles>* input_files,
125 std::unordered_set<uint64_t>* input_set,
126 const VersionStorageInfo* vstorage,
127 const CompactionOptions& compact_options) const;
128
129 // Is there currently a compaction involving level 0 taking place
130 bool IsLevel0CompactionInProgress() const {
131 return !level0_compactions_in_progress_.empty();
132 }
133
134 // Return true if the passed key range overlap with a compaction output
135 // that is currently running.
136 bool RangeOverlapWithCompaction(const Slice& smallest_user_key,
137 const Slice& largest_user_key,
138 int level) const;
139
140 // Stores the minimal range that covers all entries in inputs in
141 // *smallest, *largest.
142 // REQUIRES: inputs is not empty
143 void GetRange(const CompactionInputFiles& inputs, InternalKey* smallest,
144 InternalKey* largest) const;
145
146 // Stores the minimal range that covers all entries in inputs1 and inputs2
147 // in *smallest, *largest.
148 // REQUIRES: inputs is not empty
149 void GetRange(const CompactionInputFiles& inputs1,
150 const CompactionInputFiles& inputs2, InternalKey* smallest,
151 InternalKey* largest) const;
152
153 // Stores the minimal range that covers all entries in inputs
154 // in *smallest, *largest.
155 // REQUIRES: inputs is not empty (at least on entry have one file)
156 void GetRange(const std::vector<CompactionInputFiles>& inputs,
1e59de90
TL
157 InternalKey* smallest, InternalKey* largest,
158 int exclude_level) const;
7c673cae
FG
159
160 int NumberLevels() const { return ioptions_.num_levels; }
161
162 // Add more files to the inputs on "level" to make sure that
163 // no newer version of a key is compacted to "level+1" while leaving an older
164 // version in a "level". Otherwise, any Get() will search "level" first,
165 // and will likely return an old/stale value for the key, since it always
166 // searches in increasing order of level to find the value. This could
167 // also scramble the order of merge operands. This function should be
168 // called any time a new Compaction is created, and its inputs_[0] are
169 // populated.
170 //
171 // Will return false if it is impossible to apply this compaction.
172 bool ExpandInputsToCleanCut(const std::string& cf_name,
173 VersionStorageInfo* vstorage,
11fdf7f2
TL
174 CompactionInputFiles* inputs,
175 InternalKey** next_smallest = nullptr);
7c673cae
FG
176
177 // Returns true if any one of the parent files are being compacted
178 bool IsRangeInCompaction(VersionStorageInfo* vstorage,
179 const InternalKey* smallest,
180 const InternalKey* largest, int level, int* index);
181
182 // Returns true if the key range that `inputs` files cover overlap with the
183 // key range of a currently running compaction.
184 bool FilesRangeOverlapWithCompaction(
1e59de90
TL
185 const std::vector<CompactionInputFiles>& inputs, int level,
186 int penultimate_level) const;
7c673cae
FG
187
188 bool SetupOtherInputs(const std::string& cf_name,
189 const MutableCFOptions& mutable_cf_options,
190 VersionStorageInfo* vstorage,
191 CompactionInputFiles* inputs,
192 CompactionInputFiles* output_level_inputs,
1e59de90
TL
193 int* parent_index, int base_index,
194 bool only_expand_towards_right = false);
7c673cae
FG
195
196 void GetGrandparents(VersionStorageInfo* vstorage,
197 const CompactionInputFiles& inputs,
198 const CompactionInputFiles& output_level_inputs,
199 std::vector<FileMetaData*>* grandparents);
200
11fdf7f2
TL
201 void PickFilesMarkedForCompaction(const std::string& cf_name,
202 VersionStorageInfo* vstorage,
203 int* start_level, int* output_level,
204 CompactionInputFiles* start_level_inputs);
205
206 bool GetOverlappingL0Files(VersionStorageInfo* vstorage,
207 CompactionInputFiles* start_level_inputs,
208 int output_level, int* parent_index);
209
7c673cae
FG
210 // Register this compaction in the set of running compactions
211 void RegisterCompaction(Compaction* c);
212
213 // Remove this compaction from the set of running compactions
214 void UnregisterCompaction(Compaction* c);
215
216 std::set<Compaction*>* level0_compactions_in_progress() {
217 return &level0_compactions_in_progress_;
218 }
219 std::unordered_set<Compaction*>* compactions_in_progress() {
220 return &compactions_in_progress_;
221 }
222
1e59de90
TL
223 const InternalKeyComparator* icmp() const { return icmp_; }
224
7c673cae 225 protected:
1e59de90 226 const ImmutableOptions& ioptions_;
7c673cae
FG
227
228// A helper function to SanitizeCompactionInputFiles() that
229// sanitizes "input_files" by adding necessary files.
230#ifndef ROCKSDB_LITE
231 virtual Status SanitizeCompactionInputFilesForAllLevels(
232 std::unordered_set<uint64_t>* input_files,
233 const ColumnFamilyMetaData& cf_meta, const int output_level) const;
234#endif // ROCKSDB_LITE
235
236 // Keeps track of all compactions that are running on Level0.
237 // Protected by DB mutex
238 std::set<Compaction*> level0_compactions_in_progress_;
239
240 // Keeps track of all compactions that are running.
241 // Protected by DB mutex
242 std::unordered_set<Compaction*> compactions_in_progress_;
243
244 const InternalKeyComparator* const icmp_;
245};
246
7c673cae 247#ifndef ROCKSDB_LITE
f67539c2
TL
248// A dummy compaction that never triggers any automatic
249// compaction.
7c673cae
FG
250class NullCompactionPicker : public CompactionPicker {
251 public:
1e59de90 252 NullCompactionPicker(const ImmutableOptions& ioptions,
7c673cae
FG
253 const InternalKeyComparator* icmp)
254 : CompactionPicker(ioptions, icmp) {}
255 virtual ~NullCompactionPicker() {}
256
257 // Always return "nullptr"
f67539c2
TL
258 Compaction* PickCompaction(
259 const std::string& /*cf_name*/,
260 const MutableCFOptions& /*mutable_cf_options*/,
20effc67 261 const MutableDBOptions& /*mutable_db_options*/,
f67539c2
TL
262 VersionStorageInfo* /*vstorage*/, LogBuffer* /* log_buffer */,
263 SequenceNumber /* earliest_memtable_seqno */) override {
7c673cae
FG
264 return nullptr;
265 }
266
267 // Always return "nullptr"
11fdf7f2
TL
268 Compaction* CompactRange(const std::string& /*cf_name*/,
269 const MutableCFOptions& /*mutable_cf_options*/,
20effc67 270 const MutableDBOptions& /*mutable_db_options*/,
11fdf7f2
TL
271 VersionStorageInfo* /*vstorage*/,
272 int /*input_level*/, int /*output_level*/,
f67539c2 273 const CompactRangeOptions& /*compact_range_options*/,
11fdf7f2
TL
274 const InternalKey* /*begin*/,
275 const InternalKey* /*end*/,
276 InternalKey** /*compaction_end*/,
f67539c2 277 bool* /*manual_conflict*/,
1e59de90
TL
278 uint64_t /*max_file_num_to_ignore*/,
279 const std::string& /*trim_ts*/) override {
7c673cae
FG
280 return nullptr;
281 }
282
283 // Always returns false.
284 virtual bool NeedsCompaction(
11fdf7f2 285 const VersionStorageInfo* /*vstorage*/) const override {
7c673cae
FG
286 return false;
287 }
288};
289#endif // !ROCKSDB_LITE
290
f67539c2
TL
291// Attempts to find an intra L0 compaction conforming to the given parameters.
292//
293// @param level_files Metadata for L0 files.
294// @param min_files_to_compact Minimum number of files required to
295// do the compaction.
296// @param max_compact_bytes_per_del_file Maximum average size in bytes per
297// file that is going to get deleted by
298// the compaction.
299// @param max_compaction_bytes Maximum total size in bytes (in terms
300// of compensated file size) for files
301// to be compacted.
302// @param [out] comp_inputs If a compaction was found, will be
303// initialized with corresponding input
304// files. Cannot be nullptr.
305//
306// @return true iff compaction was found.
307bool FindIntraL0Compaction(
308 const std::vector<FileMetaData*>& level_files, size_t min_files_to_compact,
309 uint64_t max_compact_bytes_per_del_file, uint64_t max_compaction_bytes,
310 CompactionInputFiles* comp_inputs,
311 SequenceNumber earliest_mem_seqno = kMaxSequenceNumber);
494da23a 312
1e59de90 313CompressionType GetCompressionType(const VersionStorageInfo* vstorage,
7c673cae
FG
314 const MutableCFOptions& mutable_cf_options,
315 int level, int base_level,
316 const bool enable_compression = true);
317
20effc67
TL
318CompressionOptions GetCompressionOptions(
319 const MutableCFOptions& mutable_cf_options,
320 const VersionStorageInfo* vstorage, int level,
321 const bool enable_compression = true);
11fdf7f2 322
f67539c2 323} // namespace ROCKSDB_NAMESPACE