/Users/deen/code/yugabyte-db/src/yb/rocksdb/compaction_filter.h
Line | Count | Source |
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 | | // Copyright (c) 2013 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 | | // The following only applies to changes made to this file as part of YugaByte development. |
10 | | // |
11 | | // Portions Copyright (c) YugaByte, Inc. |
12 | | // |
13 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
14 | | // in compliance with the License. You may obtain a copy of the License at |
15 | | // |
16 | | // http://www.apache.org/licenses/LICENSE-2.0 |
17 | | // |
18 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
19 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
20 | | // or implied. See the License for the specific language governing permissions and limitations |
21 | | // under the License. |
22 | | // |
23 | | |
24 | | #ifndef YB_ROCKSDB_COMPACTION_FILTER_H |
25 | | #define YB_ROCKSDB_COMPACTION_FILTER_H |
26 | | |
27 | | #include <memory> |
28 | | #include <string> |
29 | | #include <vector> |
30 | | |
31 | | #include "yb/util/slice.h" |
32 | | #include "yb/rocksdb/metadata.h" |
33 | | #include "yb/rocksdb/db/version_edit.h" |
34 | | |
35 | | namespace rocksdb { |
36 | | |
37 | | class SliceTransform; |
38 | | |
39 | | // Context information of a compaction run |
40 | | struct CompactionFilterContext { |
41 | | // Does this compaction run include all data files |
42 | | bool is_full_compaction; |
43 | | // Is this compaction requested by the client (true), |
44 | | // or is it occurring as an automatic compaction process |
45 | | bool is_manual_compaction; |
46 | | }; |
47 | | |
48 | | // CompactionFilter allows an application to modify/delete a key-value at |
49 | | // the time of compaction. |
50 | | |
51 | | YB_DEFINE_ENUM(FilterDecision, (kKeep)(kDiscard)); |
52 | | |
53 | | class CompactionFilter { |
54 | | public: |
55 | | // Context information of a compaction run |
56 | | struct Context { |
57 | | // Does this compaction run include all data files |
58 | | bool is_full_compaction; |
59 | | // Is this compaction requested by the client (true), |
60 | | // or is it occurring as an automatic compaction process |
61 | | bool is_manual_compaction; |
62 | | // Which column family this compaction is for. |
63 | | uint32_t column_family_id; |
64 | | }; |
65 | | |
66 | 3.17k | virtual ~CompactionFilter() {} |
67 | | |
68 | | // The compaction process invokes this |
69 | | // method for kv that is being compacted. A return value |
70 | | // of false indicates that the kv should be preserved in the |
71 | | // output of this compaction run and a return value of true |
72 | | // indicates that this key-value should be removed from the |
73 | | // output of the compaction. The application can inspect |
74 | | // the existing value of the key and make decision based on it. |
75 | | // |
76 | | // Key-Values that are results of merge operation during compaction are not |
77 | | // passed into this function. Currently, when you have a mix of Put()s and |
78 | | // Merge()s on a same key, we only guarantee to process the merge operands |
79 | | // through the compaction filters. Put()s might be processed, or might not. |
80 | | // |
81 | | // When the value is to be preserved, the application has the option |
82 | | // to modify the existing_value and pass it back through new_value. |
83 | | // value_changed needs to be set to true in this case. |
84 | | // |
85 | | // If you use snapshot feature of RocksDB (i.e. call GetSnapshot() API on a |
86 | | // DB* object), CompactionFilter might not be very useful for you. Due to |
87 | | // guarantees we need to maintain, compaction process will not call Filter() |
88 | | // on any keys that were written before the latest snapshot. In other words, |
89 | | // compaction will only call Filter() on keys written after your most recent |
90 | | // call to GetSnapshot(). In most cases, Filter() will not be called very |
91 | | // often. This is something we're fixing. See the discussion at: |
92 | | // https://www.facebook.com/groups/mysqlonrocksdb/permalink/999723240091865/ |
93 | | // |
94 | | // If multithreaded compaction is being used *and* a single CompactionFilter |
95 | | // instance was supplied via Options::compaction_filter, this method may be |
96 | | // called from different threads concurrently. The application must ensure |
97 | | // that the call is thread-safe. |
98 | | // |
99 | | // If the CompactionFilter was created by a factory, then it will only ever |
100 | | // be used by a single thread that is doing the compaction run, and this |
101 | | // call does not need to be thread-safe. However, multiple filters may be |
102 | | // in existence and operating concurrently. |
103 | | // |
104 | | // The last paragraph is not true if you set max_subcompactions to more than |
105 | | // 1. In that case, subcompaction from multiple threads may call a single |
106 | | // CompactionFilter concurrently. |
107 | | virtual FilterDecision Filter(int level, |
108 | | const Slice& key, |
109 | | const Slice& existing_value, |
110 | | std::string* new_value, |
111 | | bool* value_changed) = 0; |
112 | | |
113 | | // The compaction process invokes this method on every merge operand. If this |
114 | | // method returns true, the merge operand will be ignored and not written out |
115 | | // in the compaction output |
116 | | // |
117 | | // Note: If you are using a TransactionDB, it is not recommended to implement |
118 | | // FilterMergeOperand(). If a Merge operation is filtered out, TransactionDB |
119 | | // may not realize there is a write conflict and may allow a Transaction to |
120 | | // Commit that should have failed. Instead, it is better to implement any |
121 | | // Merge filtering inside the MergeOperator. |
122 | | virtual bool FilterMergeOperand(int level, const Slice& key, |
123 | 160k | const Slice& operand) const { |
124 | 160k | return false; |
125 | 160k | } |
126 | | |
127 | 3.07k | virtual void CompactionFinished() { |
128 | 3.07k | } |
129 | | |
130 | | // By default, compaction will only call Filter() on keys written after the |
131 | | // most recent call to GetSnapshot(). However, if the compaction filter |
132 | | // overrides IgnoreSnapshots to make it return false, the compaction filter |
133 | | // will be called even if the keys were written before the last snapshot. |
134 | | // This behavior is to be used only when we want to delete a set of keys |
135 | | // irrespective of snapshots. In particular, care should be taken |
136 | | // to understand that the values of thesekeys will change even if we are |
137 | | // using a snapshot. |
138 | 3.15k | virtual bool IgnoreSnapshots() const { return false; } |
139 | | |
140 | | // Gives the compaction filter an opportunity to return a "user frontier" that will be used to |
141 | | // update the frontier stored in the version edit metadata when the compaction result is |
142 | | // installed. |
143 | | // |
144 | | // As a concrete use case, we use this to pass the history cutoff timestamp from the DocDB |
145 | | // compaction filter into the version edit metadata. See DocDBCompactionFilter. |
146 | 2.06k | virtual UserFrontierPtr GetLargestUserFrontier() const { return nullptr; } |
147 | | |
148 | | // Returns a name that identifies this compaction filter. |
149 | | // The name will be printed to LOG file on start up for diagnosis. |
150 | | virtual const char* Name() const = 0; |
151 | | |
152 | | // Returns a list of the ranges which should be considered "live" on this tablet. Returns an empty |
153 | | // list if the whole key range of the tablet should be considered live. Returned ranges are |
154 | | // represented as pairs of Slices denoting the beginning and end of the range in user space. |
155 | 2.06k | virtual std::vector<std::pair<Slice, Slice>> GetLiveRanges() const { return {}; } |
156 | | }; |
157 | | |
158 | | // Each compaction will create a new CompactionFilter allowing the |
159 | | // application to know about different compactions |
160 | | class CompactionFilterFactory { |
161 | | public: |
162 | 382k | virtual ~CompactionFilterFactory() { } |
163 | | |
164 | | virtual std::unique_ptr<CompactionFilter> CreateCompactionFilter( |
165 | | const CompactionFilter::Context& context) = 0; |
166 | | |
167 | | // Returns a name that identifies this compaction filter factory. |
168 | | virtual const char* Name() const = 0; |
169 | | }; |
170 | | |
171 | | // Makes a decision about whether or not to exclude a file in a compaction based on whether |
172 | | // or not the file has expired. If expired, file will be removed at the end of compaction. |
173 | | class CompactionFileFilter { |
174 | | public: |
175 | 24 | virtual ~CompactionFileFilter() = default; |
176 | | |
177 | | // Determines whether to keep or discard a file based on the file's metadata. |
178 | | virtual FilterDecision Filter(const FileMetaData* file) = 0; |
179 | | |
180 | | // Returns a name that identifies this compaction filter. |
181 | | // The name will be printed to LOG file on start up for diagnosis. |
182 | | virtual const char* Name() const = 0; |
183 | | }; |
184 | | |
185 | | // Each compaction will create a new CompactionFileFilter allowing each |
186 | | // filter to have unique state when making expiration decisions. |
187 | | class CompactionFileFilterFactory { |
188 | | public: |
189 | 11 | virtual ~CompactionFileFilterFactory() { } |
190 | | |
191 | | // Creates a unique pointer to a new CompactionFileFilter. |
192 | | virtual std::unique_ptr<CompactionFileFilter> CreateCompactionFileFilter( |
193 | | const std::vector<FileMetaData*>& input_files) = 0; |
194 | | |
195 | | // Returns a name that identifies this compaction filter factory. |
196 | | virtual const char* Name() const = 0; |
197 | | }; |
198 | | |
199 | | } // namespace rocksdb |
200 | | |
201 | | #endif // YB_ROCKSDB_COMPACTION_FILTER_H |