Coverage Report

Created: 2026-10-23 22:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/storage/compaction/cumulative_compaction_policy.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include <stddef.h>
21
#include <stdint.h>
22
23
#include <memory>
24
#include <string>
25
#include <string_view>
26
#include <unordered_map>
27
#include <vector>
28
29
#include "common/config.h"
30
#include "storage/rowset/rowset_fwd.h"
31
32
namespace doris {
33
34
class Tablet;
35
class BaseTablet;
36
struct Version;
37
38
inline constexpr std::string_view CUMULATIVE_SIZE_BASED_POLICY = "size_based";
39
40
/// This class CumulativeCompactionPolicy is the base class of cumulative compaction policy.
41
/// It defines the policy to do cumulative compaction. It has different derived classes, which implements
42
/// concrete cumulative compaction algorithm. The policy is configured by conf::cumulative_compaction_policy.
43
/// The policy functions is the main steps to do cumulative compaction. For example, how to pick candidate
44
/// rowsets from tablet using current policy, how to calculate the cumulative point and how to calculate
45
/// the tablet cumulative compaction score and so on.
46
class CumulativeCompactionPolicy {
47
public:
48
    /// Constructor function of CumulativeCompactionPolicy,
49
    /// it needs tablet pointer to access tablet method.
50
    /// param tablet, the shared pointer of tablet
51
818
    CumulativeCompactionPolicy() {}
52
53
    /// Destructor function of CumulativeCompactionPolicy.
54
818
    virtual ~CumulativeCompactionPolicy() {}
55
56
    /// Calculate the cumulative compaction score of the tablet. This function uses rowsets meta and current
57
    /// cumulative point to calculative the score of tablet. The score depends on the concrete algorithm of policy.
58
    /// In general, the score represents the segments nums to do cumulative compaction in total rowsets. The more
59
    /// score tablet gets, the earlier it can do  cumulative compaction.
60
    /// param all_rowsets, all rowsets in tablet.
61
    /// param current_cumulative_point, current cumulative point value.
62
    /// return score, the result score after calculate.
63
    virtual uint32_t calc_cumulative_compaction_score(Tablet* tablet) = 0;
64
65
    /// Pick input rowsets from candidate rowsets for compaction. This function is pure virtual function.
66
    /// Its implementation depends on concrete compaction policy.
67
    /// param candidate_rowsets, the candidate_rowsets vector container to pick input rowsets
68
    /// return input_rowsets, the vector container as return
69
    /// return last_delete_version, if has delete rowset, record the delete version from input_rowsets
70
    /// return compaction_score, calculate the compaction score of picked input rowset
71
    virtual int pick_input_rowsets(Tablet* tablet,
72
                                   const std::vector<RowsetSharedPtr>& candidate_rowsets,
73
                                   const int64_t max_compaction_score,
74
                                   const int64_t min_compaction_score,
75
                                   std::vector<RowsetSharedPtr>* input_rowsets,
76
                                   Version* last_delete_version, size_t* compaction_score,
77
                                   bool allow_delete = false) = 0;
78
79
    /// Update tablet's cumulative point after cumulative compaction finished. This function is pure virtual function.
80
    /// Each derived has its own update policy which depends on its concrete algorithm. When the cumulative point moves
81
    /// after output rowset, then output rowset will do base compaction next time.
82
    /// param input_rowsets, the picked input rowset to do compaction just now
83
    /// param output_rowset, the result rowset after compaction
84
    virtual void update_cumulative_point(Tablet* tablet,
85
                                         const std::vector<RowsetSharedPtr>& input_rowsets,
86
                                         RowsetSharedPtr output_rowset,
87
                                         Version& last_delete_version) = 0;
88
89
    /// Calculate tablet's cumulative point before compaction. This calculation just executes once when the tablet compacts
90
    /// first time after BE initialization and then motion of cumulative point depends on update_cumulative_point policy.
91
    /// This function is pure virtual function. In general, the cumulative point splits the rowsets into two parts:
92
    /// base rowsets, cumulative rowsets.
93
    /// param all_rowsets, all rowsets in the tablet
94
    /// param current_cumulative_point, current cumulative position
95
    /// return cumulative_point, the result of calculating cumulative point position
96
    virtual void calculate_cumulative_point(Tablet* tablet,
97
                                            const RowsetMetaMapContainer& all_rowsets,
98
                                            int64_t current_cumulative_point,
99
                                            int64_t* cumulative_point) = 0;
100
101
    // Updates the compaction level of a tablet after a compaction operation.
102
    virtual int64_t get_compaction_level(Tablet* tablet,
103
                                         const std::vector<RowsetSharedPtr>& input_rowsets,
104
                                         RowsetSharedPtr output_rowset) = 0;
105
106
    /// Fetch cumulative policy name
107
    virtual std::string_view name() = 0;
108
};
109
110
/// SizeBased cumulative compaction policy implementation. SizeBased policy which derives CumulativeCompactionPolicy is a optimized
111
/// version of num based cumulative compaction policy. This policy also uses linear structure to compact rowsets. The cumulative rowsets
112
/// can do compaction when they are in same level size. And when output rowset exceeds the promotion radio of base size or min promotion
113
/// size, it will do base compaction. This policy is targeting the use cases requiring lower write amplification, trading off read
114
/// amplification and space amplification.
115
class SizeBasedCumulativeCompactionPolicy final : public CumulativeCompactionPolicy {
116
public:
117
    /// Constructor function of SizeBasedCumulativeCompactionPolicy,
118
    /// it needs tablet pointer to access tablet method.
119
    /// param tablet, the shared pointer of tablet
120
    SizeBasedCumulativeCompactionPolicy(
121
            int64_t promotion_size = config::compaction_promotion_size_mbytes * 1024 * 1024,
122
            double promotion_ratio = config::compaction_promotion_ratio,
123
            int64_t promotion_min_size = config::compaction_promotion_min_size_mbytes * 1024 * 1024,
124
            int64_t promotion_version_count = config::compaction_promotion_version_count,
125
            int64_t compaction_min_size = config::compaction_min_size_mbytes * 1024 * 1024);
126
127
    /// Destructor function of SizeBasedCumulativeCompactionPolicy.
128
740
    ~SizeBasedCumulativeCompactionPolicy() {}
129
130
    /// SizeBased cumulative compaction policy implements calculate cumulative point function.
131
    /// When the first time the tablet does compact, this calculation is executed. Its main policy is to find first rowset
132
    /// which does not satisfied the promotion conditions.
133
    void calculate_cumulative_point(Tablet* tablet, const RowsetMetaMapContainer& all_rowsets,
134
                                    int64_t current_cumulative_point,
135
                                    int64_t* cumulative_point) override;
136
137
    /// SizeBased cumulative compaction policy implements pick input rowsets function.
138
    /// Its main policy is picking rowsets from candidate rowsets by comparing accumulative compaction_score,
139
    /// max_cumulative_compaction_num_singleton_deltas or checking whether there is delete version rowset,
140
    /// and choose those rowset in the same level to do cumulative compaction.
141
    int pick_input_rowsets(Tablet* tablet, const std::vector<RowsetSharedPtr>& candidate_rowsets,
142
                           const int64_t max_compaction_score, const int64_t min_compaction_score,
143
                           std::vector<RowsetSharedPtr>* input_rowsets,
144
                           Version* last_delete_version, size_t* compaction_score,
145
                           bool allow_delete = false) override;
146
147
    /// SizeBased cumulative compaction policy implements update cumulative point function.
148
    /// Its main policy is judging the output rowset size whether satisfied the promotion size.
149
    /// If it satisfied, this policy will update the cumulative point.
150
    void update_cumulative_point(Tablet* tablet, const std::vector<RowsetSharedPtr>& input_rowsets,
151
                                 RowsetSharedPtr _output_rowset,
152
                                 Version& last_delete_version) override;
153
154
    /// Num based cumulative compaction policy implements calc cumulative compaction score function.
155
    /// Its main policy is calculating the accumulative compaction score after current cumulative_point in tablet.
156
    uint32_t calc_cumulative_compaction_score(Tablet* tablet) override;
157
158
    int64_t get_compaction_level(Tablet* tablet, const std::vector<RowsetSharedPtr>& input_rowsets,
159
0
                                 RowsetSharedPtr output_rowset) override {
160
0
        return 0;
161
0
    }
162
163
108
    std::string_view name() override { return CUMULATIVE_SIZE_BASED_POLICY; }
164
165
private:
166
    /// calculate promotion size using current base rowset meta size and promotion configs
167
    void _calc_promotion_size(Tablet* tablet, RowsetMetaSharedPtr base_rowset_meta,
168
                              int64_t* promotion_size);
169
170
    /// calculate the disk size belong to which level, the level is divide by power of 2
171
    /// between compaction_promotion_size_mbytes and 1KB
172
    int64_t _level_size(const int64_t size);
173
174
    /// when policy calculate cumulative_compaction_score, update promotion size at the same time
175
    void _refresh_tablet_promotion_size(Tablet* tablet, int64_t promotion_size);
176
177
private:
178
    /// cumulative compaction promotion size, unit is byte.
179
    int64_t _promotion_size;
180
    /// cumulative compaction promotion ratio of base rowset total disk size.
181
    double _promotion_ratio;
182
    /// cumulative compaction promotion min size, unit is byte.
183
    int64_t _promotion_min_size;
184
    // cululative compaction promotion version count, only works for unique key MoW table
185
    int64_t _promotion_version_count;
186
    /// lower bound size to do compaction compaction.
187
    int64_t _compaction_min_size;
188
};
189
190
/// The factory of CumulativeCompactionPolicy, it can product different policy according to the `policy` parameter.
191
class CumulativeCompactionPolicyFactory {
192
public:
193
    /// Static factory function. It can product different policy according to the `policy` parameter and use tablet ptr
194
    /// to construct the policy. Now it can product size based and num based policies.
195
    static std::shared_ptr<CumulativeCompactionPolicy> create_cumulative_compaction_policy(
196
            const std::string_view& compaction_policy);
197
198
    /// Returns the policy registered under `compaction_policy` in `policies`, which must hold
199
    /// the size-based policy. The name comes from the meta of tablet `tablet_id`; a name this
200
    /// build does not know falls back to the size-based policy with a warning, the same as
201
    /// create_cumulative_compaction_policy() does.
202
    static std::shared_ptr<CumulativeCompactionPolicy> get_cumulative_compaction_policy(
203
            const std::unordered_map<std::string_view, std::shared_ptr<CumulativeCompactionPolicy>>&
204
                    policies,
205
            std::string_view compaction_policy, int64_t tablet_id);
206
};
207
208
} // namespace doris