Skip to main content

Module incremental

Module incremental 

Source
Expand description

Incremental driver over the row-pattern Nfa.

The batch matcher Nfa::find_matches_dynamic rescans the whole buffer from position 0 on every call. Under append-only input (rows arriving in ORDER BY order) most of that work is redundant: AFTER MATCH SKIP makes the matches before a committed skip-resume point immutable, because no row appended after them can change a match that already terminated before them. This wrapper keeps that skip-resume point as a scan cursor and, on each IncrementalMatcher::advance, reruns find_matches_dynamic only over the suffix that can still change — never reimplementing the NFA traversal (and so never bypassing its greedy/reluctant preference, fresh-visited-scope, or WITHIN invariants).

Matches are anchored by row seq rather than buffer position so they stay stable when earlier rows are evicted and finalized (see IncrementalMatcher::finalize_evicted_prefix); positions are an internal detail of the current buffer.

Freezing rule (see IncrementalMatcher::advance): a match — and the scan region behind it up to its skip-resume position — freezes only once every position in that region is dead at the current boundary per Nfa::reaches_boundary_alive (the same liveness predicate row eviction uses). A dead position’s scan outcome can never change under appended rows, because no path from it can consume past the old boundary; so the whole region’s scan behavior — matches found, gaps skipped, and the resume point — is final. Any live position (a still-open trailing match, or a gap where a longer, higher-preference alternative is still in flight) keeps the region provisional and re-attempted on the next advance.

A late (out-of-order) row that sorts before rows already fed is handled by IncrementalMatcher::truncate_from_seq: it rolls state back to a scan-resume point at or before the insertion, re-verifying the freezing gate against the truncation boundary (freezing is only sound against the boundary it was checked at), after which the caller re-feeds the corrected sorted suffix through advance.

Scaffolding note: under the EVENT_TIME plan the upstream EowcSort makes out-of-order feeds unreachable, so truncate_from_seq and the provisional-changelog helpers (diff_provisional, plan_provisional_rows, fed_seqs) have no production caller and are compiled #[cfg(test)]. They are kept — proven by the randomized differential oracle in this module — as the invalidation machinery a future input mode that revises already-fed rows (e.g. an emit-on-update or arrival-order mode) would need, rather than shipped as live surface.

Structs§

IncrementalMatcher
Incremental wrapper around Nfa::find_matches_dynamic for append-only input.
OffsetMatcher 🔒
Adapts a CandidateMatcher so that a scan over the suffix [offset, ..) sees suffix-relative positions 0, 1, ... while the underlying matcher still resolves absolute buffer positions. This lets us drive Nfa::find_matches_dynamic over just the mutable suffix using the same matcher the batch path uses, without adding a start-offset parameter to the NFA.
Seq
A row’s stable sequence number: the buffer-table PK tiebreaker minted at ingest, unique for the buffer’s lifetime and stable across eviction. A newtype (not a bare i64) so a seq can never be confused with a buffer position (a bare usize) at the incremental-matcher seams — the two are different integer spaces. The raw i64 is unwrapped (.0) only at the two real boundaries: the state-table storage (de)serialization, and where the _match_id output datum is built.
SeqMatch
A match anchored by row seqs (stable across eviction), not buffer positions. start_seq is the seq of the match’s first row; end_seq is one past the seq of its last row (so end_seq - start_seq equals the row count only while seqs are contiguous). labels[i] is the pattern variable bound to the match’s i-th row.

Enums§

Finalized
Outcome of IncrementalMatcher::finalize_evicted_prefix: whether the matcher could finalize the evicted prefix in place (staying reusable) or the eviction shape forces the caller to drop and rebuild it.