1 | #pragma once |
2 | |
3 | #include <Columns/IColumn.h> |
4 | #include <unordered_map> |
5 | |
6 | namespace DB |
7 | { |
8 | |
9 | class ChunkInfo |
10 | { |
11 | public: |
12 | virtual ~ChunkInfo() = default; |
13 | ChunkInfo() = default; |
14 | }; |
15 | |
16 | using ChunkInfoPtr = std::shared_ptr<const ChunkInfo>; |
17 | |
18 | class Chunk |
19 | { |
20 | public: |
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 | |
88 | private: |
89 | Columns columns; |
90 | UInt64 num_rows = 0; |
91 | ChunkInfoPtr chunk_info; |
92 | |
93 | void checkNumRowsIsConsistent(); |
94 | }; |
95 | |
96 | using Chunks = std::vector<Chunk>; |
97 | |
98 | /// Block extension to support delayed defaults. AddingDefaultsProcessor uses it to replace missing values with column defaults. |
99 | class ChunkMissingValues : public ChunkInfo |
100 | { |
101 | public: |
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 | |
110 | private: |
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 | |