1#pragma once
2
3#include <Core/Block.h>
4
5
6namespace DB
7{
8
9
10/** Merging consecutive passed blocks to specified minimum size.
11 *
12 * (But if one of input blocks has already at least specified size,
13 * then don't merge it with neighbours, even if neighbours are small.)
14 *
15 * Used to prepare blocks to adequate size for INSERT queries,
16 * because such storages as Memory, StripeLog, Log, TinyLog...
17 * store or compress data in blocks exactly as passed to it,
18 * and blocks of small size are not efficient.
19 *
20 * Order of data is kept.
21 */
22class SquashingTransform
23{
24public:
25 /// Conditions on rows and bytes are OR-ed. If one of them is zero, then corresponding condition is ignored.
26 SquashingTransform(size_t min_block_size_rows_, size_t min_block_size_bytes_, bool reserve_memory_ = false);
27
28 /// When not ready, you need to pass more blocks to add function.
29 struct Result
30 {
31 bool ready = false;
32 MutableColumns columns;
33
34 Result(bool ready_) : ready(ready_) {}
35 Result(MutableColumns && columns_) : ready(true), columns(std::move(columns_)) {}
36 };
37
38 /** Add next block and possibly returns squashed block.
39 * At end, you need to pass empty block. As the result for last (empty) block, you will get last Result with ready = true.
40 */
41 Result add(MutableColumns && columns);
42
43private:
44 size_t min_block_size_rows;
45 size_t min_block_size_bytes;
46 bool reserve_memory;
47
48 MutableColumns accumulated_columns;
49
50 void append(MutableColumns && columns);
51
52 bool isEnoughSize(const MutableColumns & columns);
53 bool isEnoughSize(size_t rows, size_t bytes) const;
54};
55
56}
57