1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
#pragma once
#include <base/types.h>
#include <Storages/MergeTree/MergeSelector.h>
#include <Storages/TTLDescription.h>
#include <map>
namespace DB
{
/** Merge selector, which is used to remove values with expired ttl.
* It selects parts to merge by greedy algorithm:
* 1. Finds part with the most earliest expired ttl and includes it to result.
* 2. Tries to find the longest range of parts with expired ttl, that includes part from step 1.
* Finally, merge selector updates TTL merge timer for the selected partition
*/
class ITTLMergeSelector : public IMergeSelector
{
public:
using PartitionIdToTTLs = std::map<String, time_t>;
ITTLMergeSelector(PartitionIdToTTLs & merge_due_times_, time_t current_time_, Int64 merge_cooldown_time_, bool dry_run_)
: current_time(current_time_)
, merge_due_times(merge_due_times_)
, merge_cooldown_time(merge_cooldown_time_)
, dry_run(dry_run_)
{
}
PartsRange select(
const PartsRanges & parts_ranges,
size_t max_total_size_to_merge) override;
/// Get TTL value for part, may depend on child type and some settings in
/// constructor.
virtual time_t getTTLForPart(const IMergeSelector::Part & part) const = 0;
/// Sometimes we can check that TTL already satisfied using information
/// stored in part and don't assign merge for such part.
virtual bool isTTLAlreadySatisfied(const IMergeSelector::Part & part) const = 0;
protected:
time_t current_time;
private:
PartitionIdToTTLs & merge_due_times;
Int64 merge_cooldown_time;
bool dry_run;
};
/// Select parts to merge using information about delete TTL. Depending on flag
/// only_drop_parts can use max or min TTL value.
class TTLDeleteMergeSelector : public ITTLMergeSelector
{
public:
using PartitionIdToTTLs = std::map<String, time_t>;
TTLDeleteMergeSelector(PartitionIdToTTLs & merge_due_times_, time_t current_time_, Int64 merge_cooldown_time_,
bool only_drop_parts_, bool dry_run_)
: ITTLMergeSelector(merge_due_times_, current_time_, merge_cooldown_time_, dry_run_)
, only_drop_parts(only_drop_parts_) {}
time_t getTTLForPart(const IMergeSelector::Part & part) const override;
/// Delete TTL should be checked only by TTL time, there are no other ways
/// to satisfy it.
bool isTTLAlreadySatisfied(const IMergeSelector::Part &) const override;
private:
bool only_drop_parts;
};
/// Select parts to merge using information about recompression TTL and
/// compression codec of existing parts.
class TTLRecompressMergeSelector : public ITTLMergeSelector
{
public:
TTLRecompressMergeSelector(PartitionIdToTTLs & merge_due_times_, time_t current_time_, Int64 merge_cooldown_time_,
const TTLDescriptions & recompression_ttls_, bool dry_run_)
: ITTLMergeSelector(merge_due_times_, current_time_, merge_cooldown_time_, dry_run_)
, recompression_ttls(recompression_ttls_)
{}
/// Return part min recompression TTL.
time_t getTTLForPart(const IMergeSelector::Part & part) const override;
/// Checks that part's codec is not already equal to required codec
/// according to recompression TTL. It doesn't make sense to assign such
/// merge.
bool isTTLAlreadySatisfied(const IMergeSelector::Part & part) const override;
private:
TTLDescriptions recompression_ttls;
};
}
|