| 473 | } |
| 474 | |
| 475 | Status GroupingAggregator::AddBatchStreaming( |
| 476 | RuntimeState* state, RowBatch* out_batch, RowBatch* child_batch, bool* eos) { |
| 477 | SCOPED_TIMER(streaming_timer_); |
| 478 | RETURN_IF_ERROR(QueryMaintenance(state)); |
| 479 | num_input_rows_ += child_batch->num_rows(); |
| 480 | |
| 481 | int remaining_capacity[PARTITION_FANOUT]; |
| 482 | bool ht_needs_expansion = false; |
| 483 | for (int i = 0; i < PARTITION_FANOUT; ++i) { |
| 484 | HashTable* hash_tbl = GetHashTable(i); |
| 485 | remaining_capacity[i] = hash_tbl->NumInsertsBeforeResize(); |
| 486 | ht_needs_expansion |= remaining_capacity[i] < child_batch->num_rows(); |
| 487 | } |
| 488 | |
| 489 | // Stop expanding hash tables if we're not reducing the input sufficiently. As our |
| 490 | // hash tables expand out of each level of cache hierarchy, every hash table lookup |
| 491 | // will take longer. We also may not be able to expand hash tables because of memory |
| 492 | // pressure. In this case HashTable::CheckAndResize() will fail. In either case we |
| 493 | // should always use the remaining space in the hash table to avoid wasting memory. |
| 494 | if (ht_needs_expansion && ShouldExpandPreaggHashTables()) { |
| 495 | for (int i = 0; i < PARTITION_FANOUT; ++i) { |
| 496 | HashTable* ht = GetHashTable(i); |
| 497 | if (remaining_capacity[i] < child_batch->num_rows()) { |
| 498 | SCOPED_TIMER(ht_resize_timer_); |
| 499 | bool resized; |
| 500 | RETURN_IF_ERROR( |
| 501 | ht->CheckAndResize(child_batch->num_rows(), ht_ctx_.get(), &resized)); |
| 502 | if (resized) { |
| 503 | remaining_capacity[i] = ht->NumInsertsBeforeResize(); |
| 504 | } |
| 505 | } |
| 506 | } |
| 507 | } |
| 508 | |
| 509 | TPrefetchMode::type prefetch_mode = state->query_options().prefetch_mode; |
| 510 | int64_t num_row_out_batch_old = out_batch->num_rows(); |
| 511 | GroupingAggregatorConfig::AddBatchStreamingImplFn fn |
| 512 | = add_batch_streaming_impl_fn_.load(); |
| 513 | if (fn != nullptr) { |
| 514 | RETURN_IF_ERROR(fn(this, agg_idx_, needs_serialize_, |
| 515 | prefetch_mode, child_batch, out_batch, ht_ctx_.get(), remaining_capacity)); |
| 516 | } else { |
| 517 | RETURN_IF_ERROR(AddBatchStreamingImpl(agg_idx_, needs_serialize_, prefetch_mode, |
| 518 | child_batch, out_batch, ht_ctx_.get(), remaining_capacity)); |
| 519 | } |
| 520 | *eos = (streaming_idx_ == 0); |
| 521 | DCHECK_GE(out_batch->num_rows(), num_row_out_batch_old); |
| 522 | num_rows_returned_ += out_batch->num_rows() - num_row_out_batch_old; |
| 523 | COUNTER_SET(num_passthrough_rows_, num_rows_returned_); |
| 524 | return Status::OK(); |
| 525 | } |
| 526 | |
| 527 | Status GroupingAggregator::InputDone() { |
| 528 | return MoveHashPartitions(num_input_rows_); |
no test coverage detected