1#pragma once
2
3#include <tuple>
4#include <Core/Types.h>
5#include <common/DayNum.h>
6#include <Storages/MergeTree/MergeTreeDataFormatVersion.h>
7
8
9namespace DB
10{
11
12/// Information about partition and the range of blocks contained in the part.
13/// Allows determining if parts are disjoint or one part fully contains the other.
14struct MergeTreePartInfo
15{
16 String partition_id;
17 Int64 min_block = 0;
18 Int64 max_block = 0;
19 UInt32 level = 0;
20 Int64 mutation = 0; /// If the part has been mutated or contains mutated parts, is equal to mutation version number.
21
22 MergeTreePartInfo() = default;
23
24 MergeTreePartInfo(String partition_id_, Int64 min_block_, Int64 max_block_, UInt32 level_)
25 : partition_id(std::move(partition_id_)), min_block(min_block_), max_block(max_block_), level(level_)
26 {
27 }
28
29 MergeTreePartInfo(String partition_id_, Int64 min_block_, Int64 max_block_, UInt32 level_, Int64 mutation_)
30 : partition_id(std::move(partition_id_)), min_block(min_block_), max_block(max_block_), level(level_), mutation(mutation_)
31 {
32 }
33
34 bool operator<(const MergeTreePartInfo & rhs) const
35 {
36 return std::forward_as_tuple(partition_id, min_block, max_block, level, mutation)
37 < std::forward_as_tuple(rhs.partition_id, rhs.min_block, rhs.max_block, rhs.level, rhs.mutation);
38 }
39
40 bool operator==(const MergeTreePartInfo & rhs) const
41 {
42 return !(*this != rhs);
43 }
44
45 bool operator!=(const MergeTreePartInfo & rhs) const
46 {
47 return *this < rhs || rhs < *this;
48 }
49
50 /// Get block number that can be used to determine which mutations we still need to apply to this part
51 /// (all mutations with version greater than this block number).
52 Int64 getDataVersion() const { return mutation ? mutation : min_block; }
53
54 /// True if contains rhs (this part is obtained by merging rhs with some other parts or mutating rhs)
55 bool contains(const MergeTreePartInfo & rhs) const
56 {
57 return partition_id == rhs.partition_id /// Parts for different partitions are not merged
58 && min_block <= rhs.min_block
59 && max_block >= rhs.max_block
60 && level >= rhs.level
61 && mutation >= rhs.mutation;
62 }
63
64 /// True if parts do not intersect in any way.
65 bool isDisjoint(const MergeTreePartInfo & rhs) const
66 {
67 return partition_id != rhs.partition_id
68 || min_block > rhs.max_block
69 || max_block < rhs.min_block;
70 }
71
72 String getPartName() const;
73 String getPartNameV0(DayNum left_date, DayNum right_date) const;
74 UInt64 getBlocksCount() const
75 {
76 return static_cast<UInt64>(max_block - min_block + 1);
77 }
78
79 static MergeTreePartInfo fromPartName(const String & part_name, MergeTreeDataFormatVersion format_version);
80
81 static bool tryParsePartName(const String & dir_name, MergeTreePartInfo * part_info, MergeTreeDataFormatVersion format_version);
82
83 static void parseMinMaxDatesFromPartName(const String & part_name, DayNum & min_date, DayNum & max_date);
84
85 static bool contains(const String & outer_part_name, const String & inner_part_name, MergeTreeDataFormatVersion format_version);
86
87 static constexpr UInt32 MAX_LEVEL = 999999999;
88 static constexpr UInt32 MAX_BLOCK_NUMBER = 999999999;
89};
90
91/// Information about detached part, which includes its prefix in
92/// addition to the above fields.
93struct DetachedPartInfo : public MergeTreePartInfo
94{
95 String dir_name;
96 String prefix;
97
98 String disk;
99
100 /// If false, MergeTreePartInfo is in invalid state (directory name was not successfully parsed).
101 bool valid_name;
102
103 static bool tryParseDetachedPartName(const String & dir_name, DetachedPartInfo & part_info, MergeTreeDataFormatVersion format_version);
104};
105
106using DetachedPartsInfo = std::vector<DetachedPartInfo>;
107
108}
109