MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / generate

Method generate

src/Processors/Transforms/NegativeLimitByTransform.cpp:258–339  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

256}
257
258Chunk NegativeLimitByTransform::generate()
259{
260 if (!offset_rows_dropped)
261 {
262 /// Drop trailing `offset` rows per group, then release the hash table and per-group
263 /// state - from here on `candidate_list` alone carries the answer in input order.
264 for (auto & window : group_windows)
265 dropOffsetRows(window);
266 offset_rows_dropped = true;
267 releaseHashTable(data);
268 hash_method_context.reset();
269 std::vector<GroupWindow>{}.swap(group_windows);
270 }
271
272 if (candidate_list.empty())
273 return {};
274
275 /// At this point, `candidate_list` contains all the rows that will be part of the output.
276 /// Per grouping key we have at most `group_length` rows. `candidate_list` holds the data in
277 /// input order, so we can emit from the head of the list.
278
279 /// Coalesce consecutive slices sharing one source chunk into a single output chunk.
280 /// This avoids emitting many tiny chunks when the grouping key has high cardinality.
281 auto coalesce_slice_begin = candidate_list.begin();
282 auto columns_ptr = coalesce_slice_begin->columns;
283 auto coalesce_slice_end = std::next(coalesce_slice_begin);
284 while (coalesce_slice_end != candidate_list.end() && coalesce_slice_end->columns == columns_ptr)
285 ++coalesce_slice_end;
286
287 Chunk chunk;
288 if (std::next(coalesce_slice_begin) == coalesce_slice_end) /// Only one slice in the chunk
289 {
290 chunk = materializeSliceToChunkIfNeeded(*coalesce_slice_begin);
291 }
292 else
293 {
294 const Columns & source = *columns_ptr;
295 UInt64 chunk_size = source.front()->size();
296
297 /// Compute some statistics to pick an optimized materialization strategy below.
298 UInt64 num_output_rows = 0;
299 UInt64 first_slice_start_row = coalesce_slice_begin->start;
300 UInt64 last_slice_end_row = 0;
301 for (auto it = coalesce_slice_begin; it != coalesce_slice_end; ++it)
302 {
303 num_output_rows += it->length;
304 last_slice_end_row = it->start + it->length;
305 }
306
307 if (num_output_rows == chunk_size)
308 {
309 /// Every row of the source chunk survived across different keys.
310 chunk = Chunk(Columns(source), num_output_rows);
311 }
312 else if (last_slice_end_row - first_slice_start_row == num_output_rows)
313 {
314 /// Slices form one contiguous segment - single cut per column, which is more efficient than mask+filter.
315 Columns result;

Callers

nothing calls this directly

Calls 15

releaseHashTableFunction · 0.85
ColumnsClass · 0.85
isColumnConstFunction · 0.85
nextFunction · 0.50
ChunkClass · 0.50
resetMethod · 0.45
swapMethod · 0.45
emptyMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected