| 134 | |
| 135 | template <typename TSortingHeap> |
| 136 | void MergingSortedBlockInputStream::merge(MutableColumns & merged_columns, TSortingHeap & queue) |
| 137 | { |
| 138 | size_t merged_rows = 0; |
| 139 | |
| 140 | /** Increase row counters. |
| 141 | * Return true if it's time to finish generating the current data block. |
| 142 | */ |
| 143 | auto count_row_and_check_limit = [&, this]() |
| 144 | { |
| 145 | ++total_merged_rows; |
| 146 | if (limit && total_merged_rows == limit) |
| 147 | { |
| 148 | // std::cerr << "Limit reached\n"; |
| 149 | cancel(false); |
| 150 | finished = true; |
| 151 | return true; |
| 152 | } |
| 153 | |
| 154 | ++merged_rows; |
| 155 | return merged_rows >= max_block_size; |
| 156 | }; |
| 157 | |
| 158 | /// Take rows in required order and put them into `merged_columns`, while the number of rows are no more than `max_block_size` |
| 159 | while (queue.isValid()) |
| 160 | { |
| 161 | auto current = queue.current(); |
| 162 | |
| 163 | /** And what if the block is totally less or equal than the rest for the current cursor? |
| 164 | * Or is there only one data source left in the queue? Then you can take the entire block on current cursor. |
| 165 | */ |
| 166 | if (current->isFirst() |
| 167 | && (queue.size() == 1 |
| 168 | || (queue.size() >= 2 && current.totallyLessOrEquals(queue.nextChild())))) |
| 169 | { |
| 170 | // std::cerr << "current block is totally less or equals\n"; |
| 171 | |
| 172 | /// If there are already data in the current block, we first return it. We'll get here again the next time we call the merge function. |
| 173 | if (merged_rows != 0) |
| 174 | { |
| 175 | //std::cerr << "merged rows is non-zero\n"; |
| 176 | return; |
| 177 | } |
| 178 | |
| 179 | /// Actually, current->order stores source number (i.e. cursors[current->order] == current) |
| 180 | size_t source_num = current->order; |
| 181 | |
| 182 | if (source_num >= cursors.size()) |
| 183 | throw Exception("Logical error in MergingSortedBlockInputStream", ErrorCodes::LOGICAL_ERROR); |
| 184 | |
| 185 | for (size_t i = 0; i < num_columns; ++i) |
| 186 | merged_columns[i] = IColumn::mutate(std::move(source_blocks[source_num].getByPosition(i).column)); |
| 187 | |
| 188 | // std::cerr << "copied columns\n"; |
| 189 | |
| 190 | merged_rows = merged_columns.at(0)->size(); |
| 191 | |
| 192 | /// Limit output |
| 193 | if (limit && total_merged_rows + merged_rows > limit) |
nothing calls this directly
no test coverage detected