refactor(hash-aggr): Simplify aggregate hash table with tempated functions#23324
refactor(hash-aggr): Simplify aggregate hash table with tempated functions#233242010YOUY01 wants to merge 2 commits into
Conversation
|
run benchmarks |
|
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing split-aggr-simplify-ht-template (a1c9b6a) to 166c040 (merge-base) diff using: tpch File an issue against this benchmark runner |
|
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing split-aggr-simplify-ht-template (a1c9b6a) to 166c040 (merge-base) diff using: tpcds File an issue against this benchmark runner |
|
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing split-aggr-simplify-ht-template (a1c9b6a) to 166c040 (merge-base) diff using: clickbench_partitioned File an issue against this benchmark runner |
Rachelint
left a comment
There was a problem hiding this comment.
Thanks @2010YOUY01 , It seems actually clear after removing duplication through this approach
|
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)Details
Resource Usagetpch — base (merge-base)
tpch — branch
File an issue against this benchmark runner |
|
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)Details
Resource Usagetpcds — base (merge-base)
tpcds — branch
File an issue against this benchmark runner |
|
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)Details
Resource Usageclickbench_partitioned — base (merge-base)
clickbench_partitioned — branch
File an issue against this benchmark runner |
|
Some thoughts about later refactoring:
What do you think about this idea @2010YOUY01 @alamb |
I think it sounds good. I think there are some other major parts too:
Looking at the names of the modules, in this directory I also feel the structure is somewhat lost
I made a PR to try and name them more consistently: |
alamb
left a comment
There was a problem hiding this comment.
Thank yoU @2010YOUY01 and @Rachelint -- this looks very nice to me
I have a few stylistic / simplification suggestions, but nothing I think is required or could not be done as a follow on
| /// Each aggregation mode chooses a different `aggregate_fn` according to its | ||
| /// semantics. For example, partial aggregation takes raw inputs, and update them | ||
| /// into stored partial states, so [`GroupsAccumulator::update_batch`] is used. | ||
| pub(super) fn aggregate_batch_inner<F>( |
There was a problem hiding this comment.
can you please document somewhere what these arguments are? Specifically the &[usize] and usize arguments?
Something like
/// Function used by [`AggregateHashTable::aggregate_batch_inner`] to update one
/// accumulator with one evaluated input batch.
///
/// Arguments:
/// * accumulator to update.
/// * accumulator's evaluated arguments and optional filter.
/// * `&[usize]` with one group index per input row, mapping each row to its interned group
/// * total number of groups currently interned in that buffer, including newly interned groups
pub(super) type AggregateBatchFn = fn(
&mut AggregateAccumulator,
&EvaluatedAccumulatorArgs,
&[usize],
usize,
) -> Result<()>;So then this would be something like
pub(super) fn aggregate_batch_inner<F: AggregateBatchFn>(
&mut self,
batch: &RecordBatch,
mut aggregate_fn: F
) -> Result<()>| |acc, values, group_indices, total_num_groups| { | ||
| acc.merge_batch(values, group_indices, total_num_groups) | ||
| }, |
There was a problem hiding this comment.
I think you can use the method name directly here
pub(in crate::aggregates) fn aggregate_batch(
&mut self,
batch: &RecordBatch,
) -> Result<()> {
self.aggregate_batch_inner(batch, AggregateAccumulator::merge_batch)
}| self.state = AggregateHashTableState::OutputtingMaterialized(output); | ||
| } | ||
| batch | ||
| self.next_output_batch_inner(|acc, emit_to, output| { |
There was a problem hiding this comment.
likewise here I think you can just use the method name directly
self.next_output_batch_inner(Self::materialize_partial_reduce_output)| /// | ||
| /// This is a temporary solution until blocked state management is implemented: | ||
| /// Issue: <https://github.com/apache/datafusion/issues/7065> | ||
| pub(super) fn next_output_batch_inner<F>( |
There was a problem hiding this comment.
Similarly, here I think a new typedef would help
/// Function used by [`AggregateHashTable::next_output_batch_inner`] to
/// materialize all currently buffered output for one aggregation mode.
///
/// Arguments
/// * hash table that is producing output
/// *The outputting buffer moved out of the table state
/// * output schema for the materialized [`RecordBatch`].
pub(super) type NextOutputBatchFn<AggrMode> = fn(
&AggregateHashTable<AggrMode>,
AggregateHashTableBuffer,
SchemaRef,
) -> Result<MaterializedAggregateOutput>;| Ok(()) | ||
| self.aggregate_batch_inner( | ||
| batch, | ||
| |acc, values, group_indices, total_num_groups| { |
There was a problem hiding this comment.
here too
self.aggregate_batch_inner(batch, AggregateAccumulator::merge_batch)| let mut output = state.group_values.emit(emit_to)?; | ||
|
|
||
| for acc in state.accumulators.iter_mut() { | ||
| self.next_output_batch_inner(|acc, emit_to, output| { |
There was a problem hiding this comment.
self.next_output_batch_inner(Self::materialize_partial_output)| } | ||
|
|
||
| Ok(()) | ||
| self.aggregate_batch_inner( |
There was a problem hiding this comment.
self.aggregate_batch_inner(batch, HashAggregateAccumulator::update_batch)
Which issue does this PR close?
Part of [EPIC] Split Aggregation Logic into Dedicated Streams #22710
An alternative for and closes refactor(hash-aggr): Simplify aggregate hash table #23309
Rationale for this change
See #23309 and #23309 (comment) for background.
I prefer this approach, but I want to point out the tradeoff for this PR's approach: the shared utility includes a complex lambda function argument, this makes them harder to extend. But I think it's okay since most functionality has been implemented for the refactor, and there are not likely to have new functional requirements.
What changes are included in this PR?
Are these changes tested?
Are there any user-facing changes?