Skip to content

[Refactor] Pane-width rounds without cross-stage calls: rerun Pass 2 per round, or pass an incremental Pass 2 state #1048

Open

Description

@zzylol

Example

Workload tools/dag-viewer/memo-examples/promql/ratio-of-quantiles-5m.json: one query, evaluated every minute, with max_error 0.01:

avg by (job) (quantile_over_time(0.5, data[5m]) / quantile_over_time(0.5, data[5m]) + quantile_over_time(0.9, data[5m]))

Over the complete pane-width domain, Pass 2 gives this one query 336 PaneChain shared-build groups (production numbers from #1010). That is too many to generate before a first plan exists. So the search (candidate_connection_search in crates/plan-selection/src/search/route.rs) runs in rounds:

  1. Seed round. PaneWidthDomain::SeedGrids, budget min(¼ of the remaining time, 5 s).
  2. Wider rounds. PaneWidthFrontier::next_domain yields Expanding { max_parts } domains, then Complete. Each non-complete round gets at most 5 s and 16 evaluations.
  3. Merge. The best validated plan across rounds is kept (merge_validated_rounds).

Between rounds, Pass 2 is incremental:

  • DomainProgress.local_memo keeps the memo from before state-group expansion.
  • extend_local_window_composition(&mut memo, entries, previous_domain, domain, deadline) adds only the widths new in this round.
  • expand_concrete_summary_state_groups_before then runs on a clone, because expansion can run only once on a memo.

Rounds run only when the workload has a pane window, the search is not exhaustive and does not keep every candidate, and the budget allows it. stage_pipeline with keep_every_candidate therefore always runs one Complete round.

The decision

#1047 moves the rounds into the asap-planner facade (Pass 2 → Stage 2 → Stage 3 per round) and forbids calls across stages. Pass 2 then needs one of:

  • A. Stateless (proposed first step). generate_logical_asap_memo_candidates(&pass1, entries, pane_widths, deadline) regenerates Pass 2 from scratch each round. This is simple, and no hidden state crosses stages. It repeats the window composition for widths earlier rounds already produced.
  • B. Incremental handle. Pass 2 returns its output plus an opaque Pass2State (today's local_memo + previous_domain). The facade passes the state back into the next round without reading it. This saves the repeated generation, but it adds a type that lives across rounds.

Proposal: implement A, measure it, and switch to B only if the measurement requires it.

Acceptance

Measure on the same host with a release stage_pipeline, with rounds enabled (no --exhaustive, default keep_every_candidate = false), on:

  • promql/ratio-of-quantiles-5m.json
  • the five promql/rangeheavy-*.json
  • the random mixed workloads

Compare A against main:

  • the selected plan and its cost
  • the number of rounds completed within the budget
  • Pass 2 time per round
  • total planning time
  • peak RSS

A is kept if the selected plans are identical and the total planning time and peak RSS are within the #1047 threshold (10%). Otherwise implement B and measure again.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    optimizerWorkload optimization and plan selectionrefactorwindowWindow functions, frames, panes, or temporal semantics

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions