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
338 changes: 195 additions & 143 deletions asap-query-engine/src/engines/simple/engine.rs

Large diffs are not rendered by default.

20 changes: 13 additions & 7 deletions asap-query-engine/src/engines/warm_tier/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,19 @@
//! "no data in window" (router falls over).
//! * [`WarmTierResult`] — per-series timestamped scalar samples
//! matching the shape of [`crate::engines::query_result::QueryResult::Matrix`].
//! * [`extract_promql_call`] — small AST walker that pulls the
//! outermost call's function name + numeric args. Lives here
//! rather than in `simple/engine.rs` because the existing
//! `extract_metric_and_label_keys` already handles the
//! metric-and-keys side; this is the function-name + args side.
//!
//! ## Controller unification (PromQL-shape recognition)
//!
//! The PromQL → `(function_name, args)` AST walker that used to live
//! here in `promql_extract.rs` has been folded into
//! [`controller::warm_tier_analysis::analyze_promql_for_warm_tier`].
//! That function is the single owner of "is this PromQL
//! warm-tier-answerable" knowledge — it returns a
//! [`controller::warm_tier_analysis::WarmTierAnalysis`] enumerating
//! the warm-tier-servable sub-expressions and the explicit
//! [`controller::warm_tier_analysis::UnsupportedReason`] for the rest.
//! The reducer keys off the analyzer's `required_capability` rather
//! than re-string-matching the PromQL function name.
//!
//! Phase-5 hybrid stitching (warm `[t0..t1']` + archive
//! `[t1'..t1]`) and per-window iteration (rather than today's
Expand All @@ -59,11 +67,9 @@

pub mod decoders;
pub mod delta_apply;
pub mod promql_extract;
pub mod sketch_reducer;

#[cfg(test)]
pub mod tests;

pub use promql_extract::{extract_promql_call, PromqlCall};
pub use sketch_reducer::{SketchReducer, WarmTierError, WarmTierResult};
159 changes: 0 additions & 159 deletions asap-query-engine/src/engines/warm_tier/promql_extract.rs

This file was deleted.

85 changes: 85 additions & 0 deletions asap-query-engine/src/stores/sketch_db/sketch_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,91 @@ pub enum SketchKindHandle {
CmsWithHeap,
}

// ── Controller ↔ backend Capability adapters ─────────────────────────────────
//
// `controller::warm_tier_analysis::Capability` is the canonical
// PromQL-shape-recognition output (the controller is the single owner
// of "is this PromQL warm-tier-answerable" knowledge — see
// `controller/src/warm_tier_analysis.rs`). The backend's `Capability`
// here is the source-of-truth for INDEXED sketch instances (driven by
// the OTLP receive path). The two enums are kept structurally
// identical and the backend adapts at the boundary so the controller
// crate stays free of any backend dep.
//
// `SketchKindHandle::Any` from the controller side maps to ALL
// concrete handles when used in capability matching — the backend's
// `is_compatible_with` helper consumes that semantics so callers don't
// need to enumerate the cross product.

impl From<controller::warm_tier_analysis::SketchKindHandle> for SketchKindHandle {
fn from(h: controller::warm_tier_analysis::SketchKindHandle) -> Self {
use controller::warm_tier_analysis::SketchKindHandle as C;
match h {
C::DDSketch => SketchKindHandle::DDSketch,
C::Kll => SketchKindHandle::Kll,
C::Hll => SketchKindHandle::Hll,
C::CountSketch => SketchKindHandle::CountSketch,
C::CountMin => SketchKindHandle::CountMin,
C::CmsWithHeap => SketchKindHandle::CmsWithHeap,
// `Any` has no single concrete handle. Callers that need
// to match against a specific instance should use
// `Capability::is_satisfied_by` instead of `From` for the
// handle directly. Defensive default: return DDSketch (the
// QuantileApprox catalog default) so a stray `Any` doesn't
// panic, though the canonical flow goes through
// `Capability::is_satisfied_by`.
C::Any => SketchKindHandle::DDSketch,
}
}
}

impl Capability {
/// True when the indexed sketch instance's capability satisfies
/// the controller-side required capability. The controller emits
/// `SketchKindHandle::Any` to mean "any implementation in the
/// family is acceptable" (e.g. QuantileApprox(Any) is satisfied
/// by both DDSketch and KLL); concrete handles must match
/// exactly.
pub fn is_satisfied_by(&self, indexed: &Capability) -> bool {
use controller::warm_tier_analysis::SketchKindHandle as Any;
let _ = Any::Any; // silence unused-import warning when compiled standalone
match (self, indexed) {
(Capability::QuantileApprox(_), Capability::QuantileApprox(_)) => true,
(Capability::CardinalityApprox, Capability::CardinalityApprox) => true,
// FrequencyTopk(CmsWithHeap) is the only sub-variant the
// warm tier can answer top-k against (CountMin /
// CountSketch carry no heap). Match exactly on the inner
// handle so the reducer's MissingHeap path stays
// accessible.
(Capability::FrequencyTopk(req), Capability::FrequencyTopk(have))
if req == have =>
{
true
}
_ => false,
}
}
}

/// Adapt a controller-side analyzed Capability into the backend
/// `Capability` enum. Used by the engine warm-tier hook to compare
/// the analyzer's required-capability against the index's recorded
/// per-instance capability. `SketchKindHandle::Any` from the
/// controller side is preserved as the catalog default for the
/// outer family (DDSketch for QuantileApprox); call sites that need
/// the "matches any concrete impl" semantic should call
/// [`Capability::is_satisfied_by`] instead.
impl From<controller::warm_tier_analysis::Capability> for Capability {
fn from(c: controller::warm_tier_analysis::Capability) -> Self {
use controller::warm_tier_analysis::Capability as C;
match c {
C::QuantileApprox(h) => Capability::QuantileApprox(h.into()),
C::CardinalityApprox => Capability::CardinalityApprox,
C::FrequencyTopk(h) => Capability::FrequencyTopk(h.into()),
}
}
}

/// Sketch-instance configuration carried per-Metric on the OTLP wire
/// (Phase 2 lifted these from per-DP up to the parent sketch container).
/// Backend reads the relevant variant at ingest time and stores it in
Expand Down
5 changes: 5 additions & 0 deletions controller/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,8 @@ pub mod stage_split;
pub mod store;
pub mod types;
pub mod types_v2;
/// PromQL → warm-tier candidate analyzer. Phase-9 unification of the
/// per-`Capability` dispatch knowledge that previously lived in
/// `asap-query-engine/src/engines/warm_tier/promql_extract.rs`. See
/// the module docs for the full PromQL shape coverage matrix.
pub mod warm_tier_analysis;
Loading