Skip to content

refactor(stage1): top-k reuse and finer-aggregate reads as one operator over groups (#1203 2a-3) - #1220

Closed
zzylol wants to merge 2 commits into
refactor/1203-2a-2-summary-results-inputsfrom
refactor/1203-2a-3-topk-finer-aggregate
Closed

zzylol wants to merge 2 commits into
refactor/1203-2a-2-summary-results-inputsfrom
refactor/1203-2a-3-topk-finer-aggregate

Conversation

@zzylol

@zzylol zzylol commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #1218; part of #1203, tracked in #1207 (PR 2a-3).

Merge unit. This PR merges into main only together with the rest of #1207's merge unit (steps 1a–6, #1207 "Order"): interim items below are deleted by a later PR in the unit.

Why

#1203 decided one operator per candidate, every intermediate result its own memo group. #1218 switched rules 3 and 8 and added the shared add_candidate_over_groups. This PR switches rules 4 (top-k reuse) and 5 (finer aggregate), which still added two-operator chains.

What

  • Rule 4 (topk): each top-k consumer copy is one operator over groups: Project over a Limit(k) group over the shared ranking group. The shared Sort and Limit(k_max) ranking producers are found or added with Stage 0's equality (find_or_add_producer) instead of append_producer's origin-and-parts reuse. The exact-only copies of input groups (exact_input_group) are found or added with find_or_add_group; their exact guarantee is what keeps them apart from the group they copy.
  • Rule 5 (finer_aggregate): a finer-aggregate read with a compensating filter is Aggregate over a Filter group over the finer group; without a filter it was already one operator.
  • Plans unchanged: no snapshot file changes; Stage 2 candidate counts identical on every snapshot input.

New abstractions not in #1207 or the doc: decisions (2026-11-05)

Per #1207's interface policy, these names are not defined by #1207, #1203 or section 3 of memo-groups-properties-requirements.md. #1207's steps 1a–6 merge into main as one merge unit (#1207, Order), so an interim abstraction may stay in this PR only when a later PR of the unit deletes it; none reaches main. Rows marked Pending approval are not deleted by any PR in the unit and need the user's decision.

Abstraction What it is for Decision
exact-only copy of a group (exact_input_group's group) top-k's exact input Interim, deleted by 2b (an exactness need is the family or the group, #1203)

How

Both rules call reuse::add_candidate_over_groups (#1218) where they called append_reader, and top-k calls reuse::find_or_add_producer where it called append_producer. No new functions.

Representation / rules / enumeration

  • (a) Representation. Unchanged types. Candidates of rules 3, 4, 5 and 8 are one operator over groups; rules 1, 2, 6, 7, 9 and step 10 still add chains.
  • (b) Rules. Rules 4 and 5 extend the memo through find_or_add_group. Their matching is unchanged: top-k already checked exactness through groups (exact_input_group recurses into input groups), and the finer-aggregate rule matches groups' logical nodes.
  • (c) Enumeration. Unchanged.

Key code interfaces added / modified

None. topk.rs and finer_aggregate.rs change only which crate-internal functions they call.

Usage. Neither rule fires on the KLL example; asap_planner --workload kll.json --run-until stage1_pass2 --format text (and the scan-widening workload) print byte-identical output before and after this PR. Two workloads where they fire, asap_planner --run-until stage1_pass2 --format text, Pass 2 output, before (#1218) vs after:

Top-k: topk by (job) (3, sum_over_time(data[1m])) and topk by (job) (5, sum_over_time(data[1m])), exact, every 10 s (data from the topk-rate snapshot workload):

# before
G3:  Aggregate top_k(k=3)  <- G2
    [1]  TopKReuse  Project ← Limit   inputs=[G7]
G4:  Aggregate top_k(k=5)  <- G2
    [1]  TopKReuse  Project ← Limit   inputs=[G7]
G6:  Sort   [0] TopKReuse  Sort   inputs=[G2]
G7:  Limit  [0] TopKReuse  Limit  inputs=[G6]       # the shared k=5 ranking
# after
G3:  Aggregate top_k(k=3)  <- G2
    [1]  TopKReuse  Project           inputs=[G8]
G4:  Aggregate top_k(k=5)  <- G2
    [1]  TopKReuse  Project           inputs=[G9]
G6:  Sort   [0] TopKReuse  Sort   inputs=[G2]
G7:  Limit  [0] TopKReuse  Limit  inputs=[G6]
G8:  Limit  [0] TopKReuse  Limit  inputs=[G7]       # k=3 of the ranking
G9:  Limit  [0] TopKReuse  Limit  inputs=[G7]       # k=5 of the ranking

(A partitioned Limit over a Limit is not legal to share when equal (NonASAPOp::is_shareable_when_equal), so each consumer's Limit is its own group.)

Finer aggregate (SQL, table metrics(ts, city, host, value)): SELECT city, host, SUM(value) FROM metrics WHERE ts > now() - INTERVAL '5' MINUTE GROUP BY city, host and SELECT SUM(value) FROM metrics WHERE ts > now() - INTERVAL '5' MINUTE AND city = 'NYC', exact:

# before
G6:   Aggregate sum(col=3)  <- G5
    [26]  Rollup  Aggregate sum(col=2) ← Filter   inputs=[G2]
# after
G6:   Aggregate sum(col=3)  <- G5
    [26]  Rollup  Aggregate sum(col=2)            inputs=[G12]
G12:  Filter  <- G2
    [0]   Rollup  Filter  inputs=[G2]             # city = 'NYC' over the per-(city, host) sums

Major algorithm changes

None.

Before this PR

Rules 4 and 5 added consumer chains through append_reader and producer groups through append_producer (reused only by origin and budget parts).

After this PR

Rules 4 and 5 add one operator over groups, with groups found by Stage 0's equality.

Deleted

  • topk.rs: its append_producer / append_reader calls and their ? error paths (finding a group cannot fail).
  • finer_aggregate.rs: its append_reader call.

append_reader and append_producer stay: rollup (6, 7) still uses them (deleted in the rollup PR).

Plan cost, Stage 2 candidates and planning time

UPDATE_SNAPSHOTS=1 left every snapshot file unchanged. Stage 2 physical candidates and --run-until stage3 wall time per snapshot input, #1218 vs this PR, release builds on one host:

snapshot Stage 2 candidates, before after seconds, before after
o11y_bench/q02 248 248 0.12 0.12
o11y_bench/q05 498 498 0.24 0.24
o11y_bench/q06 251 251 0.12 0.11
o11y_bench/q11 7 7 0.02 0.02
o11y_bench/q12 2 2 0.01 0.01
o11y_bench/q18 737 737 0.29 0.29
o11y_bench/q19 495 495 0.26 0.26
o11y_bench/q20 4 4 0.01 0.01
o11y_bench/q21 368 368 0.11 0.11
o11y_bench/q22 247 247 0.10 0.10
o11y_bench/q23 247 247 0.10 0.10
o11y_bench/q25 495 495 0.26 0.26
o11y_bench/q26 247 247 0.11 0.11
o11y_bench/q27 4 4 0.01 0.01
sketch/shared-quantiles-1h-mvp 1801 1801 0.89 0.88
sketch/nested-windows-15m-1h-mvp 2281 2281 1.23 1.23
sketch/ratio-of-quantiles-1h-mvp 1802 1802 2.54 2.49
sketch/quantile-single-mvp 201 201 0.09 0.08
sketch/quantile-grouped-mvp 108 108 0.06 0.06
sketch/topk-rate-guarantees-ignored-mvp 87 87 0.06 0.05
sketch/fuzz-issue903-raw-retained 135 135 0.08 0.08
sketch/random-mixed-seed-862-w02-q2-q7-mvp 136 136 0.09 0.09
sketch/random-mixed-seed-862-w01-q3-q8-mvp 226 226 0.11 0.11
sketch/random-mixed-seed-862-long-w01-q3-mvp 72 72 0.09 0.09
total 6.99 6.91

Second review fixes (7e3d360)

Notation (formulation → code)

Formulation (#1203, #1201, #1207) Code name in this PR
memo group $G$ MemoGroup, id MemoGroupId
candidate $v$ added to $G$ (over groups) add_candidate_over_groups, Memo::add_candidate (doc)
a group of the exact implementations of a group (no formulation term) exact_input_group

Concepts not in the formulation

Second review verification (7e3d360)

  • cargo test -p asap-types --lib: 146 passed. cargo test -p asap-logical-asap-optimization --lib: 198 passed.
  • cargo test -p asap-integration-tests --test integration -- memo_enumeration reuse_rules operator_sharing sharing_issue_regressions finer_aggregate_reuse planner_layering_example having_shared_aggregate stage1_logical_asap_optimization joint_search_equivalence sketch_rollup rollup_controlled production_rollup_workloads: 154 passed, 23 ignored (pre-existing).
  • cargo test -p asap-devtools --lib: 18 passed. --test devtools -- asap_planner:: asap_planner_acceptance:: memo_pricing::: 56 passed, 1 ignored.
  • UPDATE_SNAPSHOTS=1 cargo test --release -p asap-devtools --test corpus_snapshots -- --include-ignored: 9 passed, no file changed.
  • KLL and scan-widening --run-until stage1_pass2 --format text: byte-identical to c4f1267.
  • asap_planner --run-until stage1_pass2 --format text: byte-identical to the pre-review head c4f1267 on 35 workloads besides the two examples: the reviewer's 20 workloads, six rollup / scan-widening / avg workloads, five earlier finer-aggregate, rollup, top-k and scan-KLL examples, and random-mixed-seed-862 workloads 01–04.
  • cargo fmt --all; cargo clippy --workspace --all-targets -- -D warnings: clean.

Restack on #1218 (b8402c7)

Rebased on #1218's interface alignment: the doc's Memo::add_candidate replaces push_candidate_if_new (same equality; returns the candidate's CandidateForMemoGroupId), and #1218's CI fix of sketch_rollup::quantiles_rolled_up_keep_the_sketch_bound. Plans unchanged.

  • cargo fmt --all -- --check, cargo clippy --workspace --all-targets -- -D warnings: clean.
  • cargo test -p asap-logical-asap-optimization --lib: 198 passed.
  • cargo test -p asap-integration-tests --test integration -- memo_enumeration reuse_rules operator_sharing sharing_issue_regressions finer_aggregate_reuse planner_layering_example having_shared_aggregate stage1_logical_asap_optimization joint_search_equivalence sketch_rollup rollup_controlled production_rollup_workloads topk: 161 passed, 23 ignored (pre-existing).

Restack (2026-11-05)

On #1215's consumer naming (build_of → build_of) and #1218's one node equality in Pass 1.

  • cargo fmt --all -- --check; cargo clippy --workspace --all-targets -- -D warnings: clean; cargo test -p asap-logical-asap-optimization --lib: 197 passed.

Viewer

Viewer tests not updated for the group shape (#1203 decision 6); viewer_contract passes.

Verification

  • cargo test -p asap-logical-asap-optimization --lib: 198 passed.
  • cargo test -p asap-physical-asap-optimization: 29 passed.
  • cargo test -p asap-plan-selection --lib: 142 passed.
  • cargo test -p asap-devtools --lib: 18 passed.
  • cargo test -p asap-integration-tests --test integration -- memo_enumeration reuse_rules operator_sharing sharing_issue_regressions finer_aggregate_reuse planner_layering_example having_shared_aggregate stage1_logical_asap_optimization joint_search_equivalence sketch_rollup rollup_controlled production_rollup_workloads: 154 passed, 23 ignored (pre-existing).
  • cargo test -p asap-devtools --test devtools -- asap_planner:: asap_planner_acceptance:: memo_pricing:: viewer_contract::: 58 passed, 1 ignored.
  • UPDATE_SNAPSHOTS=1 cargo test --release -p asap-devtools --test corpus_snapshots -- --include-ignored: 9 passed, no file changed.
  • cargo fmt --all; cargo clippy --workspace --all-targets -- -D warnings: clean.
  • KLL and scan-widening --run-until stage1_pass2 --format text: byte-identical to refactor(stage1): summary readouts and inputs as one operator over groups; Memo::add_candidate; one node equality in Pass 1 (#1203 2a-2) #1218's head.

Left for 2a-4..k

Rollups (6, 7), scan widening (2), tumbling windows (1), state configurations (9) and step 10, then the deletions listed in #1215 and #1218.

@zzylol zzylol added CSE optimizer Workload optimization and plan selection refactor labels Nov 5, 2026
@zzylol
zzylol force-pushed the refactor/1203-2a-2-summary-results-inputs branch from b3c7b5a to ef701a7 Compare November 5, 2026 15:44
zzylol added a commit that referenced this pull request Nov 5, 2026
…s candidates when found

`exact_input_group` replaced the candidates of the group `find_or_add_group`
returned, also when it found an existing group. Now the exact candidates
replace the own candidate only of a group it added; a found group keeps its
candidates and gets the new ones through `push_candidate_if_new`. Top-k and
finer-aggregate reads follow #1218's interface changes (`MemoGroupId` owner,
`find_or_add_producer` without budget parts).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1M6br9PL4SDeVS1XpezKJ
@zzylol
zzylol force-pushed the refactor/1203-2a-3-topk-finer-aggregate branch from c4f1267 to 9fbfc54 Compare November 5, 2026 16:01
@zzylol
zzylol force-pushed the refactor/1203-2a-2-summary-results-inputs branch from ef701a7 to f27b38f Compare November 5, 2026 17:08
zzylol added a commit that referenced this pull request Nov 5, 2026
…s candidates when found

`exact_input_group` replaced the candidates of the group `find_or_add_group`
returned, also when it found an existing group. Now the exact candidates
replace the own candidate only of a group it added; a found group keeps its
candidates and gets the new ones through `push_candidate_if_new`. Top-k and
finer-aggregate reads follow #1218's interface changes (`MemoGroupId` owner,
`find_or_add_producer` without budget parts).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1M6br9PL4SDeVS1XpezKJ
@zzylol
zzylol force-pushed the refactor/1203-2a-3-topk-finer-aggregate branch from 9fbfc54 to 7e3d360 Compare November 5, 2026 17:23
zzylol added a commit that referenced this pull request Nov 5, 2026
…s candidates when found

`exact_input_group` replaced the candidates of the group `find_or_add_group`
returned, also when it found an existing group. Now the exact candidates
replace the own candidate only of a group it added; a found group keeps its
candidates and gets the new ones through `push_candidate_if_new`. Top-k and
finer-aggregate reads follow #1218's interface changes (`MemoGroupId` owner,
`find_or_add_producer` without budget parts).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1M6br9PL4SDeVS1XpezKJ
@zzylol
zzylol force-pushed the refactor/1203-2a-3-topk-finer-aggregate branch from 7e3d360 to e8f39e8 Compare November 5, 2026 20:19
@zzylol
zzylol force-pushed the refactor/1203-2a-2-summary-results-inputs branch from b8402c7 to 45c8d37 Compare November 5, 2026 21:13
zzylol added a commit that referenced this pull request Nov 5, 2026
…s candidates when found

`exact_input_group` replaced the candidates of the group `find_or_add_group`
returned, also when it found an existing group. Now the exact candidates
replace the own candidate only of a group it added; a found group keeps its
candidates and gets the new ones through `push_candidate_if_new`. Top-k and
finer-aggregate reads follow #1218's interface changes (`MemoGroupId` owner,
`find_or_add_producer` without budget parts).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1M6br9PL4SDeVS1XpezKJ
@zzylol
zzylol force-pushed the refactor/1203-2a-3-topk-finer-aggregate branch from e8f39e8 to c418afa Compare November 5, 2026 21:13
zzylol and others added 2 commits November 5, 2026 21:24
…or over groups

Rules 4 (top-k reuse) and 5 (finer aggregate) add their reader copies
through `add_candidate_over_groups`, so the `Limit` of a top-k read and
the compensating `Filter` of a finer-aggregate read are groups. Top-k's
sort and ranking producers are found or added with Stage 0's equality
(`find_or_add_producer`); its exact-only input groups through
`Memo::find_or_add_group`, their exact guarantee keeping them apart from
the group they copy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1M6br9PL4SDeVS1XpezKJ
…s candidates when found

`exact_input_group` replaced the candidates of the group `find_or_add_group`
returned, also when it found an existing group. Now the exact candidates
replace the own candidate only of a group it added; a found group keeps its
candidates and gets the new ones through `push_candidate_if_new`. Top-k and
finer-aggregate reads follow #1218's interface changes (`MemoGroupId` owner,
`find_or_add_producer` without budget parts).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1M6br9PL4SDeVS1XpezKJ
@zzylol

zzylol commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

Closed: replaced by #1207's new order (interfaces first, then one PR per stage), starting with PR 0 #1226. The code on this branch is reused in PRs 1–8; the branch is kept.

@zzylol zzylol closed this Nov 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CSE optimizer Workload optimization and plan selection refactor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant