1 | #include <Processors/Chunk.h> |
2 | #include <IO/WriteHelpers.h> |
3 | #include <IO/Operators.h> |
4 | |
5 | namespace DB |
6 | { |
7 | |
8 | namespace ErrorCodes |
9 | { |
10 | extern const int LOGICAL_ERROR; |
11 | extern const int POSITION_OUT_OF_BOUND; |
12 | } |
13 | |
14 | Chunk::Chunk(DB::Columns columns_, UInt64 num_rows_) : columns(std::move(columns_)), num_rows(num_rows_) |
15 | { |
16 | checkNumRowsIsConsistent(); |
17 | } |
18 | |
19 | Chunk::Chunk(Columns columns_, UInt64 num_rows_, ChunkInfoPtr chunk_info_) |
20 | : columns(std::move(columns_)), num_rows(num_rows_), chunk_info(std::move(chunk_info_)) |
21 | { |
22 | checkNumRowsIsConsistent(); |
23 | } |
24 | |
25 | static Columns unmuteColumns(MutableColumns && mut_columns) |
26 | { |
27 | Columns columns; |
28 | columns.reserve(mut_columns.size()); |
29 | for (auto & col : mut_columns) |
30 | columns.emplace_back(std::move(col)); |
31 | |
32 | return columns; |
33 | } |
34 | |
35 | Chunk::Chunk(MutableColumns columns_, UInt64 num_rows_) |
36 | : columns(unmuteColumns(std::move(columns_))), num_rows(num_rows_) |
37 | { |
38 | checkNumRowsIsConsistent(); |
39 | } |
40 | |
41 | Chunk::Chunk(MutableColumns columns_, UInt64 num_rows_, ChunkInfoPtr chunk_info_) |
42 | : columns(unmuteColumns(std::move(columns_))), num_rows(num_rows_), chunk_info(std::move(chunk_info_)) |
43 | { |
44 | checkNumRowsIsConsistent(); |
45 | } |
46 | |
47 | Chunk Chunk::clone() const |
48 | { |
49 | return Chunk(getColumns(), getNumRows()); |
50 | } |
51 | |
52 | void Chunk::setColumns(Columns columns_, UInt64 num_rows_) |
53 | { |
54 | columns = std::move(columns_); |
55 | num_rows = num_rows_; |
56 | checkNumRowsIsConsistent(); |
57 | } |
58 | |
59 | void Chunk::setColumns(MutableColumns columns_, UInt64 num_rows_) |
60 | { |
61 | columns = unmuteColumns(std::move(columns_)); |
62 | num_rows = num_rows_; |
63 | checkNumRowsIsConsistent(); |
64 | } |
65 | |
66 | void Chunk::checkNumRowsIsConsistent() |
67 | { |
68 | for (auto & column : columns) |
69 | if (column->size() != num_rows) |
70 | throw Exception("Invalid number of rows in Chunk column " + column->getName()+ ": expected " + |
71 | toString(num_rows) + ", got " + toString(column->size()), ErrorCodes::LOGICAL_ERROR); |
72 | } |
73 | |
74 | MutableColumns Chunk::mutateColumns() |
75 | { |
76 | size_t num_columns = columns.size(); |
77 | MutableColumns mut_columns(num_columns); |
78 | for (size_t i = 0; i < num_columns; ++i) |
79 | mut_columns[i] = (*std::move(columns[i])).mutate(); |
80 | |
81 | columns.clear(); |
82 | num_rows = 0; |
83 | |
84 | return mut_columns; |
85 | } |
86 | |
87 | MutableColumns Chunk::cloneEmptyColumns() const |
88 | { |
89 | size_t num_columns = columns.size(); |
90 | MutableColumns mut_columns(num_columns); |
91 | for (size_t i = 0; i < num_columns; ++i) |
92 | mut_columns[i] = columns[i]->cloneEmpty(); |
93 | return mut_columns; |
94 | } |
95 | |
96 | Columns Chunk::detachColumns() |
97 | { |
98 | num_rows = 0; |
99 | return std::move(columns); |
100 | } |
101 | |
102 | void Chunk::addColumn(ColumnPtr column) |
103 | { |
104 | if (column->size() != num_rows) |
105 | throw Exception("Invalid number of rows in Chunk column " + column->getName()+ ": expected " + |
106 | toString(num_rows) + ", got " + toString(column->size()), ErrorCodes::LOGICAL_ERROR); |
107 | |
108 | columns.emplace_back(std::move(column)); |
109 | } |
110 | |
111 | void Chunk::erase(size_t position) |
112 | { |
113 | if (columns.empty()) |
114 | throw Exception("Chunk is empty" , ErrorCodes::POSITION_OUT_OF_BOUND); |
115 | |
116 | if (position >= columns.size()) |
117 | throw Exception("Position " + toString(position) + " out of bound in Chunk::erase(), max position = " |
118 | + toString(columns.size() - 1), ErrorCodes::POSITION_OUT_OF_BOUND); |
119 | |
120 | columns.erase(columns.begin() + position); |
121 | } |
122 | |
123 | UInt64 Chunk::bytes() const |
124 | { |
125 | UInt64 res = 0; |
126 | for (const auto & column : columns) |
127 | res += column->byteSize(); |
128 | |
129 | return res; |
130 | } |
131 | |
132 | UInt64 Chunk::allocatedBytes() const |
133 | { |
134 | UInt64 res = 0; |
135 | for (const auto & column : columns) |
136 | res += column->allocatedBytes(); |
137 | |
138 | return res; |
139 | } |
140 | |
141 | std::string Chunk::dumpStructure() const |
142 | { |
143 | WriteBufferFromOwnString out; |
144 | for (auto & column : columns) |
145 | out << ' ' << column->dumpStructure(); |
146 | |
147 | return out.str(); |
148 | } |
149 | |
150 | |
151 | void ChunkMissingValues::setBit(size_t column_idx, size_t row_idx) |
152 | { |
153 | RowsBitMask & mask = rows_mask_by_column_id[column_idx]; |
154 | mask.resize(row_idx + 1); |
155 | mask[row_idx] = true; |
156 | } |
157 | |
158 | const ChunkMissingValues::RowsBitMask & ChunkMissingValues::getDefaultsBitmask(size_t column_idx) const |
159 | { |
160 | static RowsBitMask none; |
161 | auto it = rows_mask_by_column_id.find(column_idx); |
162 | if (it != rows_mask_by_column_id.end()) |
163 | return it->second; |
164 | return none; |
165 | } |
166 | |
167 | } |
168 | |