1#pragma once
2#include <vector>
3#include <Storages/MergeTree/MarkRange.h>
4
5namespace DB
6{
7
8/// Class contains information about index granularity in rows of MergeTreeDataPart
9/// Inside it contains vector of partial sums of rows after mark:
10/// |-----|---|----|----|
11/// | 5 | 8 | 12 | 16 |
12/// If user doesn't specify setting adaptive_index_granularity_bytes for MergeTree* table
13/// all values in inner vector would have constant stride (default 8192).
14class MergeTreeIndexGranularity
15{
16private:
17 std::vector<size_t> marks_rows_partial_sums;
18 bool initialized = false;
19
20public:
21 MergeTreeIndexGranularity() = default;
22 explicit MergeTreeIndexGranularity(const std::vector<size_t> & marks_rows_partial_sums_);
23 MergeTreeIndexGranularity(size_t marks_count, size_t fixed_granularity);
24
25
26 /// Return count of rows between marks
27 size_t getRowsCountInRange(const MarkRange & range) const;
28 /// Return count of rows between marks
29 size_t getRowsCountInRange(size_t begin, size_t end) const;
30 /// Return sum of rows between all ranges
31 size_t getRowsCountInRanges(const MarkRanges & ranges) const;
32
33 /// Return amount of marks that contains amount of `number_of_rows` starting from
34 /// `from_mark` and possible some offset_in_rows from `from_mark`
35 /// 1 2 <- answer
36 /// |-----|---------------------------|----|----|
37 /// ^------------------------^-----------^
38 //// from_mark offset_in_rows number_of_rows
39 size_t countMarksForRows(size_t from_mark, size_t number_of_rows, size_t offset_in_rows=0) const;
40
41 /// Total marks
42 size_t getMarksCount() const;
43 /// Total rows
44 size_t getTotalRows() const;
45
46 /// Total number marks without final mark if it exists
47 size_t getMarksCountWithoutFinal() const { return getMarksCount() - hasFinalMark(); }
48
49 /// Rows after mark to next mark
50 inline size_t getMarkRows(size_t mark_index) const
51 {
52 if (mark_index == 0)
53 return marks_rows_partial_sums[0];
54 else
55 return marks_rows_partial_sums[mark_index] - marks_rows_partial_sums[mark_index - 1];
56 }
57
58 /// Return amount of rows before mark
59 size_t getMarkStartingRow(size_t mark_index) const;
60
61 /// Amount of rows after last mark
62 size_t getLastMarkRows() const
63 {
64 size_t last = marks_rows_partial_sums.size() - 1;
65 return getMarkRows(last);
66 }
67
68 size_t getLastNonFinalMarkRows() const
69 {
70 size_t last_mark_rows = getLastMarkRows();
71 if (last_mark_rows != 0)
72 return last_mark_rows;
73 return getMarkRows(marks_rows_partial_sums.size() - 2);
74 }
75
76 bool hasFinalMark() const
77 {
78 return getLastMarkRows() == 0;
79 }
80
81 bool empty() const
82 {
83 return marks_rows_partial_sums.empty();
84 }
85
86 bool isInitialized() const
87 {
88 return initialized;
89 }
90
91 void setInitialized()
92 {
93 initialized = true;
94 }
95 /// Add new mark with rows_count
96 void appendMark(size_t rows_count);
97
98 /// Add `size` of marks with `fixed_granularity` rows
99 void resizeWithFixedGranularity(size_t size, size_t fixed_granularity);
100};
101
102}
103