1#pragma once
2
3#include <Columns/IColumn.h>
4#include <unordered_map>
5
6namespace DB
7{
8
9class ChunkInfo
10{
11public:
12 virtual ~ChunkInfo() = default;
13 ChunkInfo() = default;
14};
15
16using ChunkInfoPtr = std::shared_ptr<const ChunkInfo>;
17
18class Chunk
19{
20public:
21 Chunk() = default;
22 Chunk(const Chunk & other) = delete;
23 Chunk(Chunk && other) noexcept
24 : columns(std::move(other.columns))
25 , num_rows(other.num_rows)
26 , chunk_info(std::move(other.chunk_info))
27 {
28 other.num_rows = 0;
29 }
30
31 Chunk(Columns columns_, UInt64 num_rows_);
32 Chunk(Columns columns_, UInt64 num_rows_, ChunkInfoPtr chunk_info_);
33 Chunk(MutableColumns columns_, UInt64 num_rows_);
34 Chunk(MutableColumns columns_, UInt64 num_rows_, ChunkInfoPtr chunk_info_);
35
36 Chunk & operator=(const Chunk & other) = delete;
37 Chunk & operator=(Chunk && other) noexcept
38 {
39 columns = std::move(other.columns);
40 chunk_info = std::move(other.chunk_info);
41 num_rows = other.num_rows;
42 other.num_rows = 0;
43 return *this;
44 }
45
46 Chunk clone() const;
47
48 void swap(Chunk & other)
49 {
50 columns.swap(other.columns);
51 chunk_info.swap(other.chunk_info);
52 std::swap(num_rows, other.num_rows);
53 }
54
55 void clear()
56 {
57 num_rows = 0;
58 columns.clear();
59 chunk_info.reset();
60 }
61
62 const Columns & getColumns() const { return columns; }
63 void setColumns(Columns columns_, UInt64 num_rows_);
64 void setColumns(MutableColumns columns_, UInt64 num_rows_);
65 Columns detachColumns();
66 MutableColumns mutateColumns();
67 /** Get empty columns with the same types as in block. */
68 MutableColumns cloneEmptyColumns() const;
69
70 const ChunkInfoPtr & getChunkInfo() const { return chunk_info; }
71 void setChunkInfo(ChunkInfoPtr chunk_info_) { chunk_info = std::move(chunk_info_); }
72
73 UInt64 getNumRows() const { return num_rows; }
74 UInt64 getNumColumns() const { return columns.size(); }
75 bool hasRows() const { return num_rows > 0; }
76 bool hasColumns() const { return !columns.empty(); }
77 bool empty() const { return !hasRows() && !hasColumns(); }
78 operator bool() const { return !empty(); }
79
80 void addColumn(ColumnPtr column);
81 void erase(size_t position);
82
83 UInt64 bytes() const;
84 UInt64 allocatedBytes() const;
85
86 std::string dumpStructure() const;
87
88private:
89 Columns columns;
90 UInt64 num_rows = 0;
91 ChunkInfoPtr chunk_info;
92
93 void checkNumRowsIsConsistent();
94};
95
96using Chunks = std::vector<Chunk>;
97
98/// Block extension to support delayed defaults. AddingDefaultsProcessor uses it to replace missing values with column defaults.
99class ChunkMissingValues : public ChunkInfo
100{
101public:
102 using RowsBitMask = std::vector<bool>; /// a bit per row for a column
103
104 const RowsBitMask & getDefaultsBitmask(size_t column_idx) const;
105 void setBit(size_t column_idx, size_t row_idx);
106 bool empty() const { return rows_mask_by_column_id.empty(); }
107 size_t size() const { return rows_mask_by_column_id.size(); }
108 void clear() { rows_mask_by_column_id.clear(); }
109
110private:
111 using RowsMaskByColumnId = std::unordered_map<size_t, RowsBitMask>;
112
113 /// If rows_mask_by_column_id[column_id][row_id] is true related value in Block should be replaced with column default.
114 /// It could contain less columns and rows then related block.
115 RowsMaskByColumnId rows_mask_by_column_id;
116};
117
118}
119