1#include <Storages/MergeTree/TTLMergeSelector.h>
2
3#include <cmath>
4#include <algorithm>
5
6
7namespace DB
8{
9
10IMergeSelector::PartsInPartition TTLMergeSelector::select(
11 const Partitions & partitions,
12 const size_t max_total_size_to_merge)
13{
14 using Iterator = IMergeSelector::PartsInPartition::const_iterator;
15 Iterator best_begin;
16 ssize_t partition_to_merge_index = -1;
17 time_t partition_to_merge_min_ttl = 0;
18
19 for (size_t i = 0; i < partitions.size(); ++i)
20 {
21 for (auto it = partitions[i].begin(); it != partitions[i].end(); ++it)
22 {
23 time_t ttl = only_drop_parts ? it->max_ttl : it->min_ttl;
24
25 if (ttl && (partition_to_merge_index == -1 || ttl < partition_to_merge_min_ttl))
26 {
27 partition_to_merge_min_ttl = ttl;
28 partition_to_merge_index = i;
29 best_begin = it;
30 }
31 }
32 }
33
34 if (partition_to_merge_index == -1 || partition_to_merge_min_ttl > current_time)
35 return {};
36
37 const auto & best_partition = partitions[partition_to_merge_index];
38 Iterator best_end = best_begin + 1;
39 size_t total_size = 0;
40
41 while (true)
42 {
43 time_t ttl = only_drop_parts ? best_begin->max_ttl : best_begin->min_ttl;
44
45 if (!ttl || ttl > current_time
46 || (max_total_size_to_merge && total_size > max_total_size_to_merge))
47 {
48 ++best_begin;
49 break;
50 }
51
52 total_size += best_begin->size;
53 if (best_begin == best_partition.begin())
54 break;
55
56 --best_begin;
57 }
58
59 while (best_end != best_partition.end())
60 {
61 time_t ttl = only_drop_parts ? best_end->max_ttl : best_end->min_ttl;
62
63 if (!ttl || ttl > current_time
64 || (max_total_size_to_merge && total_size > max_total_size_to_merge))
65 break;
66
67 total_size += best_end->size;
68 ++best_end;
69 }
70
71 return PartsInPartition(best_begin, best_end);
72}
73
74}
75