Rindle docs and package mapSkip to main content

Reduce

Struct Reduce 

Source
pub struct Reduce {
    pub input: NodeId,
    pub storage: StorageId,
    pub aggs: Vec<AggSpec>,
    pub partition_key: Option<Vec<ColId>>,
    pub eager: bool,
    pub schema: Schema,
    pub output: Cell<Option<OutEdge>>,
    /* private fields */
}
Expand description

Reduce: an invertible aggregate, global or grouped. The running accumulator(s) live in Graph storage under Reduce::storage, not in the struct, so they survive across fetch/push.

Fields§

§input: NodeId

Upstream input operator (the source connection, or a sub-pipeline tail).

§storage: StorageId

Scratch-state slot holding the per-group StorageValue::Reduce counters.

§aggs: Vec<AggSpec>

The aggregates this node computes, in output-column order. v1: [Count].

§partition_key: Option<Vec<ColId>>

The grouping columns, in input-row coordinates. None = global (a single immortal row); Some = one row per distinct value-tuple (top-level GROUP BY). In the output row the group columns occupy positions 0..partition_key.len().

§eager: bool

Hydration regime for the grouped case (REDUCE-DESIGN.md §8.1; moot when partition_key is None). true = eager (top-level GROUP BYView, full-fold hydrate; an Add to a no-state group births it, death deletes the slot). false = lazy (relationship aggregate → per-group constrained fetch; an Add to a no-state group is dropped and folded on the next fetch, death keeps the count-0 slot so the next Add re-births).

§schema: Schema

The synthetic output schema (REDUCE-DESIGN.md §3): [group_cols…, agg_cols…]. Global ⇒ just [count] with empty PK/sort (singleton-only, §8); grouped ⇒ the group columns are the PK and sort, then the aggregate columns.

§output: Cell<Option<OutEdge>>

The single downstream edge, wired two-phase like every fan-out-seam operator (via Graph::set_output).

Implementations§

Source§

impl Reduce

Source

pub fn global_agg(input: NodeId, storage: StorageId, spec: AggSpec) -> Reduce

A global single-aggregate reducer over input (spec). Output is a one-column [<agg>] row (no key, no sort — a singleton, §8).

Source

pub fn grouped_agg( input: NodeId, storage: StorageId, partition_key: Vec<ColId>, key_cols: Vec<&str>, spec: AggSpec, ) -> Reduce

A grouped single-aggregate reducer: one [group_key…, <agg>] row per distinct value of partition_key (input-row column indices). key_cols are the output names of the group columns (same arity/order as partition_key). The output schema’s PK and sort are the group columns (0..k, ascending), then the aggregate.

Source

pub fn count(input: NodeId, storage: StorageId) -> Reduce

A global count(*) reducer over inputglobal_agg with AggSpec::Count.

Source

pub fn sum(input: NodeId, storage: StorageId, col: ColId) -> Reduce

A global sum(col) reducer (input-row column index).

Source

pub fn avg(input: NodeId, storage: StorageId, col: ColId) -> Reduce

A global avg(col) reducer (input-row column index).

Source

pub fn count_by( input: NodeId, storage: StorageId, partition_key: Vec<ColId>, key_cols: Vec<&str>, ) -> Reduce

A grouped count(*) reducer — grouped_agg with AggSpec::Count.

Source

pub fn sum_by( input: NodeId, storage: StorageId, partition_key: Vec<ColId>, key_cols: Vec<&str>, col: ColId, ) -> Reduce

A grouped sum(col) reducer (col in input-row coordinates).

Source

pub fn avg_by( input: NodeId, storage: StorageId, partition_key: Vec<ColId>, key_cols: Vec<&str>, col: ColId, ) -> Reduce

A grouped avg(col) reducer (col in input-row coordinates).

Source

pub fn lazy(self) -> Reduce

Switch a grouped reducer to the lazy regime (REDUCE-DESIGN.md §8.1) — for a relationship aggregate whose groups a parent join fetches one at a time. A constrained fetch folds just that group (persisting even a count-0 group); a push to a group with no state is dropped (the next fetch folds it), and a group that drains to 0 keeps its slot so the next Add re-births it.

Source

pub fn with_input_types(self, input: &Schema) -> Reduce

Derive the synthetic output schema’s column_types from the input schema (design 226 §4.1): each group column preserves its input column’s declared type (partition_key[i] in input coordinates → output position i), and each aggregate column carries AggSpec::output_type. The builder chains this on every reduce it constructs; the constructors alone leave Schema::new’s all-Number default, which direct-op tests keep.

Source

pub fn evict_partition(&self, g: &Graph, constraint: &Constraint)

Delete the group slot constraint identifies — the twin of Take::evict_partition, called by Graph::evict_child_partitions when a parent leaves a bounded parent view.

A lazy grouped reducer (every relationship aggregate) never deletes a slot on its own: the grouped-delta death arm deletes only when eager, and it must stay that way — the lazy regime keeps a count-0 slot precisely so a later Add can re-birth 0 → 1 for a parent that is still in the view. Nothing else dropped a lazy slot, so a long-lived query kept one entry per parent row it ever aggregated, for the life of the query. The parent’s departure is the event that makes the slot dead, which is what this hook is.

Safe for the same reason Take::evict_partition is: both callers gate on the parent correlation being the parent’s primary key, so the group belongs to exactly the one parent that left, and a deleted lazy slot is indistinguishable from a never-folded one — the next constrained fetch re-folds it.

The constraint is in output coordinates (the join’s child key for an aggregate is 0..k, builder.rs), while Reduce::partition_key is in input coordinates — so the gate and the value extraction both work in 0..k, exactly as Reduce::fetch’s single-group path does. Matching against partition_key directly would silently evict nothing whenever the correlation is not the child’s leading columns.

Source

pub fn fetch<'g>( &'g self, g: &'g Graph, req: &FetchRequest, ) -> Box<dyn Iterator<Item = Node<'g>> + 'g>

Lazy pull. The request is ignored for the eager regimes (see the module note): global serves/folds the single accumulator; grouped folds the whole input into per-group accumulators, persists each, and emits one row per group in output-sort order. On first sight the fold seeds state; thereafter push maintains it.

Source

pub fn push<'g>(&'g self, g: &'g Graph, change: Change<'g>)

Eager push. Global maintains the one immortal accumulator (always an Edit); grouped maintains per-group accumulators with birth (Add), shift (Edit), and death (Remove at row count → 0). A same-group Edit leaves count(*) unchanged but can still move a sum/avg, so it re-folds the accumulator and emits iff the aggregate row actually changed (REDUCE-DESIGN.md §6); a Child never changes the input-row population, so it emits nothing.

Auto Trait Implementations§

§

impl !Freeze for Reduce

§

impl !RefUnwindSafe for Reduce

§

impl Send for Reduce

§

impl !Sync for Reduce

§

impl Unpin for Reduce

§

impl UnsafeUnpin for Reduce

§

impl UnwindSafe for Reduce

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.