Repository navigation
minor: share common state between the three PartitionedTopK operators - #25534
jayzhan211 wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Release the reservation before emission and correct the shared-state documentation.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
What changed in this PR
Refactors the three partitioned Top-K operators to share common state and logic without intended behavior changes.
Changes:
- Adds
PartitionedTopKBasefor shared construction, grouping, emission, and memory accounting. - Retains ranking-specific state and classification logic.
- Sorts partition key/state pairs directly and updates dense-rank tests.
| File | Summary |
|---|---|
datafusion/physical-plan/src/topk/mod.rs |
Shared implementation and operator refactor. Review findings: line 1392—moderate (2 votes), release the reservation before emission; line 1258—nit (1 vote), correct documentation of the separate converters and scratch buffers. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #25534 +/- ##
==========================================
- Coverage 82.66% 82.66% -0.01%
==========================================
Files 1147 1147
Lines 446522 446470 -52
Branches 446522 446470 -52
==========================================
- Hits 369134 369079 -55
- Misses 54988 55001 +13
+ Partials 22400 22390 -10 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@jayzhan211 can we wait for more days. I wanted to fix perf issues first then do a final refactor to avoid any potential merge conflict. |
Sure! |
kosiew
left a comment
There was a problem hiding this comment.
@jayzhan211, thanks for working on this. The refactor looks good overall. Extracting the shared partitioned Top-K machinery into PartitionedTopKBase removes a fair amount of duplication while keeping the ranking-specific logic nicely separated. I only have one optional testing suggestion below.
| /// Emit every partition in partition-key order as a stream of coalesced | ||
| /// `RecordBatch`es. `emit_partition` pushes one partition's rows, already | ||
| /// in ORDER BY order, into the coalescer. | ||
| fn emit<S>( |
There was a problem hiding this comment.
Nice refactor. One optional suggestion: could we extend test_partitioned_topk_output_batches_metric_counts_emitted_batches to assert the emitted row order as well? It already exercises multiple partitions, a small batch_size, coalescing, and the output-batch metrics through the shared emit path, so checking row order would round out the coverage here. Not blocking.
…d-topk-base # Conflicts: # datafusion/physical-plan/src/topk/mod.rs

Which issue does this PR close?
Rationale for this change
PartitionedTopK(ROW_NUMBER),PartitionedTopKRank(RANK) andPartitionedTopKDenseRank(DENSE_RANK) were added one after another, each as a copy of the previous one. They differ in the per-partition state and in how one partition's rows are classified, but every copy also repeats:Rows,k,batch_size) and their doc comments,try_newbody,insert_batch(evaluate and row-encode the partition and ORDER BY columns), plus the group-rows-by-partition loop inRANKandDENSE_RANK,insert_batch(record replacements, resize the reservation),size(), and inRANK/DENSE_RANKthe same per-partition map accounting.A fix to one copy (for example the partition-key byte accounting in
size()) has to be remembered for the other two.What changes are included in this PR?
No behaviour change.
PartitionedTopKBaseholding the shared fields, withtry_new,encode,group_by_partition,finish_batchandsizehelpers, plus apartition_states_sizehelper for the per-partition map thatRANKandDENSE_RANKboth account the same way.base+ its own state.ROW_NUMBERkeeps its single-pass admission, shared store and O(1)size();RANKandDENSE_RANKkeep theirpartition_groupsscratch map (now drained in place) and their classification loops.PartitionedTopKExecand the crate-visible signatures of the three types are unchanged. Memory consumer names are unchanged.self.scratch_rows→self.base.scratch_rows,groups.drain()→self.partition_groups.drain()).RANK/DENSE_RANKemitnow sorts(key, state)pairs directly instead of cloning every partition key into a separate sortedVecand looking each one up again, asROW_NUMBERalready does.Net: +271 / −365 lines in
topk/mod.rs.What is the testing strategy for this PR?
Covered by existing tests: the 111
topkunit tests (including the exactsize()reconstruction test forDENSE_RANKand the reservation-vs-size()invariant check forROW_NUMBER, updated only for the new field paths), thewindow_topnphysical optimizer tests and the window Top-N sqllogictests.Are there any user-facing changes?
No.