Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ ASAPQuery-backend/ # Cargo workspace
│ └── src/
│ ├── query_parser/ # PromQL/SQL parsing → intent algebra
│ ├── intent_algebra/ # shared intent representation
│ ├── sketch_algebra/ # sketch planning (+ rules/)
│ ├── physical/post_asap/ # physical adapters for Planner post-ASAP IR
│ ├── optimizer/ # plan optimization (cost/ + rules/)
│ ├── physical/ # physical plan (colored_dag/)
│ ├── emit/ # per-runtime config emission
Expand Down Expand Up @@ -233,7 +233,7 @@ that produced the current architecture:

- **Sketch placement planner** — moved into [`ASAPCollector/controller/`](https://github.com/ProjectASAP/ASAPCollector/tree/main/controller)
- **PromQL pattern matchers for the planner** — migrated into the
controller's L3 `intent_algebra` + L4 `sketch_algebra`
ASAPPlanner's post-ASAP IR plus backend physical placement
- **JSONL cold-fallback path** — deleted; the configured exact backend is the
explicit fallback described by
[query-engine implementation design](docs/developer_docs/query-engine/design.md).
Expand Down
2 changes: 1 addition & 1 deletion control_plane/proto/backend_plan.proto
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ message SummaryParams {
}
}

// ── Capability (control_plane::sketch_algebra::capability) ──────────────────
// ── Capability (control_plane::physical::post_asap::capability) ──────────────────

enum SketchKindHandle {
SKETCH_KIND_HANDLE_UNSPECIFIED = 0;
Expand Down
2 changes: 1 addition & 1 deletion control_plane/src/asap_tier_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
//! exist in real PromQL/MetricsQL; the lowerer handles the real
//! names like `quantile_over_time` and `count_over_time`).
//! - The local `Capability` / `SketchKindHandle` enums — they're now
//! re-exported from `sketch_algebra` (the single source of truth).
//! re-exported from `physical::post_asap` (the single source of truth).

use std::collections::BTreeSet;
use std::time::Duration;
Expand Down
2 changes: 1 addition & 1 deletion control_plane/src/asap_tier_implement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//! four already-distinct senses of "bind" in this stack (L2 name
//! resolution `ColumnRef → ColumnId`; the L3→L4 per-node physical
//! choice; a deployment's own L4→L5 *placement* decision, e.g.
//! `control_plane::sketch_algebra::rules::bind_*`; and this module's own
//! `control_plane::physical::post_asap::rules::bind_*`; and this module's own
//! prior usage) and deliberately names its L3→L4 step **"implementation"**
//! instead (Cascades/Volcano terminology: an *implementation rule* is
//! logical → physical, distinct from a *transformation rule*, logical →
Expand Down
18 changes: 9 additions & 9 deletions control_plane/src/emit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ pub use telegraf::emit_telegraf_toml;
pub use crate::workload::WorkloadRegistry;

use crate::physical::colored_dag::emitter::EdgeStageConfig;
use crate::sketch_algebra::physical_expr::L4Plan;
use crate::sketch_algebra::PhysicalExpr;
use crate::physical::post_asap::deployment_expr::PostAsapPlan;
use crate::physical::post_asap::PhysicalExpr;
use crate::store::WorkloadStore;
use anyhow::Result;
use planner_types::post_asap::{SketchAlgorithm, SummaryExpr, SummaryNode};
Expand Down Expand Up @@ -295,13 +295,13 @@ pub fn extract_root_sketch_kind(expr: &PhysicalExpr) -> Option<SketchAlgorithm>
}
}

fn extract_from_plan(plan: &L4Plan) -> Option<SketchAlgorithm> {
fn extract_from_plan(plan: &PostAsapPlan) -> Option<SketchAlgorithm> {
match plan {
L4Plan::Summary(node) => extract_from_node(node),
L4Plan::LetBinding { expr, child, .. } => {
PostAsapPlan::Summary(node) => extract_from_node(node),
PostAsapPlan::LetBinding { expr, child, .. } => {
extract_from_plan(expr).or_else(|| extract_from_plan(child))
}
L4Plan::Ref { .. } => None,
PostAsapPlan::Ref { .. } => None,
}
}

Expand All @@ -323,7 +323,7 @@ fn extract_from_node(node: &Rc<SummaryNode>) -> Option<SketchAlgorithm> {
SummaryExpr::SummaryEstimate { summary_input, .. } => extract_from_node(summary_input),
SummaryExpr::SummaryMerge { children } => children.iter().find_map(extract_from_node),
// Not surfaced by any `Bind*` path yet (gated on rules that
// haven't landed — see `physical_expr.rs`'s module docs).
// haven't landed — see `deployment_expr.rs`'s module docs).
SummaryExpr::SummaryJoin { .. }
| SummaryExpr::SummarySubtract { .. }
| SummaryExpr::SummaryDelete { .. }
Expand Down Expand Up @@ -389,15 +389,15 @@ pub fn collect_metric_to_family(
.get(label)
.map(|v| (label, v.as_str()))
});
let Some(physical_expr) =
let Some(deployment_expr) =
crate::physical::workload_planner::bind_workload_typed_with_item_filter(
&workload,
item_filter,
)
else {
continue;
};
if let Some(kind) = extract_root_sketch_kind(&physical_expr) {
if let Some(kind) = extract_root_sketch_kind(&deployment_expr) {
out.entry(entry.metric_name.clone())
.or_default()
.insert(kind);
Expand Down
8 changes: 4 additions & 4 deletions control_plane/src/emit/stage_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -899,7 +899,7 @@ fn build_routing_entry(metric_name: &str, cfg: &BackendStageConfig) -> JsonValue
warm_shapes.push("count");
}
// Heap-bearing kinds count too — `SummaryKind` (unlike the retired
// `sketch_algebra::SummaryKind`) promotes `with_heap` to a distinct
// `physical::post_asap::SummaryKind`) promotes `with_heap` to a distinct
// identity variant, but a topk-bound Count-Sketch/CMS aggregation
// still needs to register here exactly as it did before the split.
let has_count_sketch = kinds.iter().any(|k| {
Expand Down Expand Up @@ -3037,7 +3037,7 @@ fn build_backend_readout_json(r: &BackendReadout) -> JsonValue {
/// The wire-string key for a `SketchQuery::PointCount` readout.
///
/// `SampleValue` and `Wildcard` both wire to the legacy `"*"` sentinel
/// (`sketch_algebra::rules::bind_cms_count`, retired by Step B, used the
/// (`physical::post_asap::rules::bind_cms_count`, retired by Step B, used the
/// literal string `"*"` to mean "all rows / no specific key"; the L5
/// emitter's per-group resolution already special-cases that string) —
/// there's no real queryable column for a plain `Count`/`Frequency`
Expand All @@ -3056,7 +3056,7 @@ fn column_ref_to_wire_key(col: &ColumnRef) -> String {
/// The 5-sketch routing-connector edge YAML path (`emit_edge_yaml`'s
/// `USE_5SKETCH_ROUTING` branch and its `metric_to_family` sibling)
/// keys its fixed `FAMILY_ORDER` list and lookup maps on the 5 bare
/// families only — matching the retired `sketch_algebra::SketchAlgorithm`,
/// families only — matching the retired `physical::post_asap::SketchAlgorithm`,
/// which had no heap-bearing variant at all (`with_heap` was a
/// `SketchParams` field, invisible to anything keying on kind alone).
/// A committed heap-bearing kind (`CmsWithHeap`/`CountSketchWithHeap`,
Expand All @@ -3079,7 +3079,7 @@ fn base_family(kind: &SketchAlgorithm) -> SketchAlgorithm {
///
/// Heap-bearing is now identity, not a params flag (`SketchAlgorithm::CmsWithHeap`
/// / `CountSketchWithHeap`, set by `BindCountSketchOnTopK` — see
/// `sketch_algebra::rules::bind_cms_topk`), so this maps on `kind` alone;
/// `physical::post_asap::rules::bind_cms_topk`), so this maps on `kind` alone;
/// `params` is unused but kept for call-site stability. This is what
/// lets the backend's `policy_capability` lookup return
/// `FrequencyTopk(*WithHeap)` for heap-bearing aggregations — required
Expand Down
8 changes: 2 additions & 6 deletions control_plane/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@
//! | `controller/src/config/{stage_config*,agent,backend,asapquery_backend,precompute}.rs` | `controller/src/emit/{...}.rs` |
//!
//! Public modules to consume from `asap-query-engine`:
//! - `sketch_algebra` — `Capability` enum + `capability_for(agg_intent: &AggIntent)`
//! lookup table (Phase 4 / 5 use this to route raw-name PromQL).
//! - `intent_algebra` — `AggIntent` + `QueryExpr` DAG (canonical L3 IR;
//! `relational` carries the L2 relational IR the parsers emit and
//! `lower` lowers it to the canonical L3 types).
Expand Down Expand Up @@ -73,7 +71,6 @@ pub mod query_parser;
pub mod query_planning;
pub mod replan;
pub mod runtime_samples;
pub mod sketch_algebra;
pub mod sketch_selection;
pub mod store;
pub mod threshold_alloc;
Expand All @@ -95,9 +92,8 @@ pub mod workload;
/// the module docs for the full PromQL shape coverage matrix.
pub mod asap_tier_analysis;

/// PromQL → compositional L4 plan via `asap_aware_mapping::bind::implement_tree`.
/// Step A of the plan-shaped-serving scoping (see module doc) -- not yet
/// wired into the live serving path.
/// PromQL → ASAPPlanner's canonical post-ASAP plan via
/// `asap_aware_mapping::bind::implement_tree`.
pub mod asap_tier_implement;

/// Crate-wide test-only utilities for serialising access to process-global
Expand Down
20 changes: 10 additions & 10 deletions control_plane/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ use control_plane::metrics_exposer;
use control_plane::monitor;
use control_plane::opamp;
use control_plane::physical;
use control_plane::physical::post_asap;
use control_plane::pipeline;
use control_plane::query_parser;
use control_plane::replan;
use control_plane::runtime_samples;
use control_plane::sketch_algebra;
use control_plane::store;
use control_plane::types;
use control_plane::types_v2;
Expand Down Expand Up @@ -779,7 +779,7 @@ async fn handle_plan(State(st): State<AppState>, Json(spec): Json<QuerySpec>) ->
// is no `query_string`.
let raw_bps = plan.transmission_cost_summary.raw_bytes_per_sec;
let budgets = StageResourceBudgets::from_workload_chars(&wc);
// Everything that touches `sketch_algebra::PhysicalExpr` (which
// Everything that touches `physical::post_asap::PhysicalExpr` (which
// carries `Rc<planner_types::post_asap::SummaryNode>` since Step B of the
// plan-shaped-serving migration adopted ASAPController's own
// `Rc`-based DAG sharing) is scoped to this block and resolved down
Expand All @@ -789,7 +789,7 @@ async fn handle_plan(State(st): State<AppState>, Json(spec): Json<QuerySpec>) ->
// yield point would make its `Future` `!Send`, breaking
// `axum::Handler`.
let (plan_summary, stage_configs) = {
let mut bound_physical: Option<control_plane::sketch_algebra::PhysicalExpr> = None;
let mut bound_physical: Option<control_plane::physical::post_asap::PhysicalExpr> = None;
let mut plan_summary = None;
if let Some(ref qs) = query_string {
match parse_query_expr_canonical(qs, accuracy) {
Expand All @@ -807,7 +807,7 @@ async fn handle_plan(State(st): State<AppState>, Json(spec): Json<QuerySpec>) ->
)
};
bound_physical =
control_plane::sketch_algebra::bind_query_expr(&qe, accuracy).ok();
control_plane::physical::post_asap::bind_query_expr(&qe, accuracy).ok();
// Cost summary for the JSON response.
let plan_node = SketchAllocator::new(budgets.clone(), raw_bps).allocate(qe);
plan_summary = Some(plan_node.summarise(raw_bps));
Expand All @@ -821,9 +821,9 @@ async fn handle_plan(State(st): State<AppState>, Json(spec): Json<QuerySpec>) ->
crate::physical::colored_dag::StageConfig,
>,
> = if physical::stage_split::typed_stage_split_enabled() {
let physical_expr = bound_physical
let deployment_expr = bound_physical
.or_else(|| physical::workload_planner::bind_workload_typed(&workload));
physical_expr.and_then(|pe| physical::stage_split::split_typed_three_stage(&pe))
deployment_expr.and_then(|pe| physical::stage_split::split_typed_three_stage(&pe))
} else {
None
};
Expand Down Expand Up @@ -883,7 +883,7 @@ async fn handle_plan(State(st): State<AppState>, Json(spec): Json<QuerySpec>) ->
//
// The typed L5 stage-split is now fed by the real **L4 output**: when
// the spec carries a `query_string`, `bound_physical` holds the
// optimised L3 tree run through `sketch_algebra::bind_query_expr`.
// optimised L3 tree run through `physical::post_asap::bind_query_expr`.
// For specs that supply only explicit fields (no `query_string` to
// parse), there is no L3 tree to bind, so we fall back to
// `bind_workload_typed`, which lowers the flat `QueryWorkload`
Expand Down Expand Up @@ -1616,7 +1616,7 @@ async fn emit_bootstrap_typed(
// typed bind, so for `http_requests_total` the
// Quantile-shaped role on `http_requests_total_latency_ms`
// stays the source of the edge config.
let mut chosen: Option<(String, crate::sketch_algebra::PhysicalExpr)> = None;
let mut chosen: Option<(String, crate::physical::post_asap::PhysicalExpr)> = None;
'outer: for cand in &candidates {
for (_, wl, _) in st.workload_store.get_all_for_metric(cand) {
if let Some(expr) = physical::workload_planner::bind_workload_typed(&wl) {
Expand All @@ -1625,13 +1625,13 @@ async fn emit_bootstrap_typed(
}
}
}
let (metric, physical_expr) = chosen.ok_or_else(|| {
let (metric, deployment_expr) = chosen.ok_or_else(|| {
anyhow!(
"no registry metric binds via the typed path (all {} candidates declined)",
candidates.len()
)
})?;
let configs = physical::stage_split::split_typed_three_stage(&physical_expr)
let configs = physical::stage_split::split_typed_three_stage(&deployment_expr)
.ok_or_else(|| anyhow!("split_typed_three_stage returned None for `{metric}`"))?;

// 4. Pick the Edge stage config and emit per-runtime. The
Expand Down
26 changes: 14 additions & 12 deletions control_plane/src/physical/colored_dag/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ use planner_types::post_asap::{SummaryExpr, SummaryNode};

use crate::physical::colored_dag::dag::{ColoredDag, ColoredNode, NodeId};
use crate::physical::colored_dag::stage_id::{StageId, Topology};
use crate::sketch_algebra::physical_expr::L4Plan;
use crate::sketch_algebra::PhysicalExpr;
use crate::physical::post_asap::deployment_expr::PostAsapPlan;
use crate::physical::post_asap::PhysicalExpr;
use crate::types_v2::BindingName;

/// Errors surfaced by [`StageAllocator::allocate`].
Expand Down Expand Up @@ -124,18 +124,18 @@ impl ThreeStageWalker {
}
}

/// Recursively visit an [`L4Plan`] — the "what to compute" layer.
/// [`L4Plan::Summary`] delegates the actual per-node granularity to
/// Recursively visit an [`PostAsapPlan`] — the "what to compute" layer.
/// [`PostAsapPlan::Summary`] delegates the actual per-node granularity to
/// [`Self::visit_l4node`] (walking `planner_types::post_asap::SummaryNode`'s own DAG
/// shape); [`L4Plan::LetBinding`] / [`L4Plan::Ref`] are this crate's
/// shape); [`PostAsapPlan::LetBinding`] / [`PostAsapPlan::Ref`] are this crate's
/// own named-binding sharing mechanism, unchanged from before Step B.
fn visit_plan(&mut self, plan: &L4Plan) -> Result<(NodeId, StageId), AllocateError> {
fn visit_plan(&mut self, plan: &PostAsapPlan) -> Result<(NodeId, StageId), AllocateError> {
match plan {
L4Plan::Summary(node) => self.visit_l4node(node),
PostAsapPlan::Summary(node) => self.visit_l4node(node),

// ── LetBinding: colour by the bound expression's stage,
// and bring the binding into scope before walking the body.
L4Plan::LetBinding { name, expr, child } => {
PostAsapPlan::LetBinding { name, expr, child } => {
let id = self.reserve_node(PhysicalExpr::Committed(plan.clone()));
let (eid, expr_stage) = self.visit_plan(expr)?;
self.dag.edges.push((id, eid));
Expand All @@ -147,7 +147,7 @@ impl ThreeStageWalker {

// ── Ref: colour matches the binding's stage. Unresolved
// refs bubble up as `AllocateError::UnresolvedRef`.
L4Plan::Ref { name } => {
PostAsapPlan::Ref { name } => {
let id = self.reserve_node(PhysicalExpr::Committed(plan.clone()));
let stage = self
.scope
Expand All @@ -163,7 +163,7 @@ impl ThreeStageWalker {
/// itself, owned upstream. Every semantic node gets its own
/// [`ColoredNode`] (matching the granularity the old, locally-defined
/// `PhysicalExpr::{SketchAgg,SketchEstimate,SketchMerge}` had),
/// stored back as `PhysicalExpr::Committed(L4Plan::Summary(..))`
/// stored back as `PhysicalExpr::Committed(PostAsapPlan::Summary(..))`
/// wrapping just that sub-node, so downstream consumers
/// (`colored_dag::emitter`, `emit::mod`) keep pattern-matching
/// against the same `PhysicalExpr` shape.
Expand Down Expand Up @@ -214,7 +214,7 @@ impl ThreeStageWalker {

// ── SummaryJoin / SummarySubtract / SummaryDelete: not
// surfaced by any `Bind*` path yet (gated on rules that
// haven't landed — see `physical_expr.rs`'s module docs'
// haven't landed — see `deployment_expr.rs`'s module docs'
// predecessor note). Conservative default matching
// SummaryMerge's multi-input-combination shape until a real
// consumer picks a placement.
Expand Down Expand Up @@ -320,7 +320,9 @@ impl ThreeStageWalker {
// stage lookup keyed by binding name.
pub(crate) fn binding_stage(dag: &ColoredDag, name: &BindingName) -> Option<StageId> {
dag.nodes.iter().find_map(|n| match &n.expr {
PhysicalExpr::Committed(L4Plan::LetBinding { name: n2, .. }) if n2 == name => Some(n.stage),
PhysicalExpr::Committed(PostAsapPlan::LetBinding { name: n2, .. }) if n2 == name => {
Some(n.stage)
}
_ => None,
})
}
Expand Down
4 changes: 2 additions & 2 deletions control_plane/src/physical/colored_dag/dag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
use serde::{Deserialize, Serialize};

use crate::physical::colored_dag::stage_id::{StageId, Topology};
use crate::sketch_algebra::PhysicalExpr;
use crate::physical::post_asap::PhysicalExpr;

/// Stable position-based identifier for a node within a `ColoredDag`.
/// `NodeId(0)` is the root; depth-first walk order otherwise.
Expand Down Expand Up @@ -146,7 +146,7 @@ mod tests {
use std::rc::Rc;

use super::*;
use crate::sketch_algebra::PhysicalExpr;
use crate::physical::post_asap::PhysicalExpr;
use planner_types::pre_asap::{Column, DataType};
use planner_types::pre_asap::{QueryExpr, Schema, Source};

Expand Down
Loading
Loading