Rindle docs and package mapSkip to main content

MemorySource

Struct MemorySource 

Source
pub struct MemorySource {
    pub schema: Schema,
    /* private fields */
}
Expand description

The in-memory source. fetch seeks a BTreeCursor over a COW snapshot and drives it through source_common; write_change path-copies via Rc::make_mut so in-flight cursors keep their snapshot (the load-bearing COW property — §6).

Fields§

§schema: Schema

Static table metadata (columns + PK). The per-connection sort lives on each Connection; the schema’s own sort is reported to downstream operators that need a child ordering (e.g. join relationship streams).

Implementations§

Source§

impl MemorySource

Source

pub fn validate_rows(schema: &Schema, rows: &[Row]) -> Result<(), RindleError>

Validate that every ingest row matches the schema’s column width (WS02.4): a wrong-width row is rejected here with a RindleError::SchemaViolation rather than reaching the engine’s unchecked column index (crate::value::RowRef::col) where it would panic / abort.

Source

pub fn try_new( schema: Schema, initial: Vec<Row>, ) -> Result<MemorySource, RindleError>

Build a source over initial rows, validating each row’s width against the schema first (WS02.4). The primary index is keyed by (pk asc); initial is sorted under it and bulk-loaded (from_sorted, O(N)). Callers guarantee initial has unique primary keys (a set). Prefer this over MemorySource::new / crate::graph::Graph::add_source in production.

Source

pub fn new(schema: Schema, initial: Vec<Row>) -> MemorySource

Panicking convenience wrapper over MemorySource::try_new (tests / prototyping).

§Panics

If a row’s width does not match the schema. Prefer MemorySource::try_new or crate::graph::Graph::try_add_source in production (WS02.6).

Source

pub fn fork(&self) -> MemorySource

O(1) fork (memory-source.ts:135): a new source sharing the primary index’s COW root (one Rc bump, no deep copy). Other indexes are NOT carried (they rebuild lazily on demand, as in the JS).

Source

pub fn fork_with_indexes(&self) -> MemorySource

Like fork, but COW-carries every index (each a one-Rc bump on its B+tree root), not just the primary — the 203-MUTATOR-READS-DESIGN.md §7.3 (A) read-cache optimization. A mutator’s one-shot tx.query that sorts in an order a live query already built then shares that secondary index by COW lineage, collapsing its O(n log n) lazy build to a bump. The carried indexes are kept current by apply_change (it writes every index), so seeding the cache fork (buffer replay) and write-forwarding maintain them. Used only for the off-graph read-cache fork and its per-query fork-of-fork; the plain fork stays primary-only for the optimistic sync baselines and the other COW snapshots that want the lighter, divergence-bounded fork (OPTIMISTIC-WRITES-DESIGN.md §1.2).

Source

pub fn get_index_keys(&self) -> Vec<Sort>

Test hook: the set of index sorts currently held (indexes persist across destroy — §3.10). Mirrors getIndexKeys (memory-source.ts:252).

Source

pub fn fork_primary(&self) -> BTree

An O(1) COW fork of the primary index tree (one Rc bump). The optimistic loop’s sync/S' trees are forks of this — sharing the live tree’s node lineage is what keeps structural_diff bounded by the divergence (OPTIMISTIC-WRITES-DESIGN.md §1.2).

Source

pub fn primary_sort(&self) -> &Sort

The primary-index sort ((pk[0] asc, pk[1] asc, …)) — the comparator every fork/diff over fork_primary trees must use.

Source

pub fn get_by_pk(&self, probe: &Row) -> Option<Row>

The current row whose primary key equals probe’s (other columns ignored by the pk-only primary sort), or None. The optimistic MutationTx read path.

Source

pub fn cursors_open(&self) -> i64

Source

pub fn conn_count(&self) -> usize

Total connection slots, including freed (recyclable) ones. Stays bounded by the peak live-connection count under query churn (the slot is recycled on teardown — it does NOT grow per teardown). For metrics/tests.

Source

pub fn live_conn_count(&self) -> usize

Number of live downstream connections (readers) — 0 once every pipeline reading this source has been torn down. See ConnTable::live_conn_count.

Source

pub fn set_conn_output(&self, conn: ConnId, edge: OutEdge)

Wire a connection’s downstream edge (mirrors input.setOutput).

Source

pub fn push_candidates(&self, change: &SourceChange) -> Vec<u32>

The connection slots a write would fan out to — the push index’s candidate set (designs/205). A test probe for the guarded / dynamic-guard pruning.

Source

pub fn push_index_size(&self) -> usize

The push index’s entry count (see ConnTable::push_index_size) — a churn probe.

Source

pub fn push( &self, change: SourceChange, push_one: &dyn Fn(&Connection, SourceChange), )

Eager push: fan change to every connection (overlay live, epoch-gated), clear the overlay, then write to every index — via the backend-agnostic source_common::gen_push_and_write_with_split_edit. push_one is the graph’s downstream driver (it reads the connection’s output edge). Edit- splitting, existence asserts, and the write-after-drain ordering all live in source_common. push_one receives a SourceChange (rows); the graph turns it into a node-bearing downstream Change at the connection boundary.

Source

pub fn try_push( &self, change: SourceChange, push_one: &dyn Fn(&Connection, SourceChange), strict: bool, ) -> Result<(), RindleError>

Fallible push used by strict change validation (WS02.2). Identical fan-out to MemorySource::push but routed through the fallible source_common sibling so a malformed change (when strict) returns a RindleError::ConsistencyViolation. The memory exists/write are infallible, so they wrap in Ok.

Source

pub fn apply_change(&self, change: &SourceChange)

Apply ADD/REMOVE/EDIT to every index without the live push path’s existence asserts and without the connection fan-out — for the off-graph read-cache fork of 203-MUTATOR-READS-DESIGN.md (mutator reads). A read-cache fork has no connections, so there is nothing to fan out to; this is purely the index write that keeps the fork equal to live ⊕ this txn's buffer for its table (§4 / §4.1): it seeds the fork (replay of the table’s buffered ops) and write-forwards each later staged op. It is deliberately tolerant of the degenerate “edit a row that isn’t there” case the staging path defers to commit (WriteTxn::edit), so a later tx.query cannot panic on it.

Trait Implementations§

Source§

impl ScalarSource for MemorySource

Source§

fn unique_keys(&self) -> Vec<Vec<ColId>>

PK-only for the slice — the only statically-unique key a memory source has (its other indexes are query-derived ordering structures, not uniqueness constraints; SCALAR-SUBQUERY-DESIGN.md §4.3).

Source§

fn schema(&self) -> &Schema

The child table’s schema (column names → ColId, primary key).
Source§

fn lookup_unique(&self, bound: &[(ColId, OwnedValue)]) -> Option<Row>

The single row in which every (ColId, value) of bound holds. The caller guarantees bound covers one of Self::unique_keys, so the result is unique. None ⇒ no row matches (the empty-result fold).
Source§

impl Source for MemorySource

Source§

fn take_error(&self) -> Option<RindleError>

The in-memory backend is infallible — a fetch never parks an error.

Source§

fn fetch<'g>(&'g self, conn: ConnId, req: &FetchRequest) -> RowFlow<'g>

#fetch (the hot read path — memory-source.ts:257). Pick an index, seek a scanStart RowBound, then drive the lending cursor through the generator chain: overlay (index comparator) → start (connection comparator) → constraint (break) → filter. The two comparators differ by design when a constraint is present (§3.1). Emits rows, not nodes — the connection boundary (Graph::fetch on the SourceConn) wraps each row in a leaf node.

Source§

fn connect( &self, sort: Option<Sort>, filters: Option<ConnectionFilters>, split_edit_keys: Vec<ColId>, ) -> ConnId

Register a new connection (one downstream output). sort = None ⇒ unordered. Self-joins call this twice. Builds the Connection from the (07-compiled) filter spec + split-edit keys, and asserts the ordering includes the PK when ordered. Mirrors connect (memory-source.ts:162).
Source§

fn schema(&self) -> &Schema

The schema of rows this source vends.
Source§

fn conn_sort(&self, conn: ConnId) -> Sort

The effective sort for a connection. This can differ from the table schema’s default/primary sort, and ordered downstream operators must use this.
Source§

fn destroy(&self, conn: ConnId)

Drop a connection’s downstream edge so it stops receiving pushes. Does NOT delete the backing indexes (§3.10).
Source§

fn cursors_open(&self) -> i64

Open-cursor count — 0 ⇒ no cursor is mid-iteration and the connection is free for a write.
Source§

fn try_push( &self, change: SourceChange, push_one: &dyn Fn(&Connection, SourceChange), strict: bool, ) -> Result<(), RindleError>

Eager fallible push: fan change to every connection (overlay live, epoch-gated), clear the overlay, then write. push_one is the graph’s downstream driver. When strict, a malformed change returns a typed RindleError instead of a debug_assert. (A backend may keep a faster infallible push as an inherent method; this is the object-safe seam the graph drives.)
Source§

fn set_conn_output(&self, conn: ConnId, edge: OutEdge)

Wire a connection’s downstream output edge (mirrors input.setOutput).
Source§

fn add_guard_value(&self, conn: ConnId, value: OwnedValue)

Add a dynamic push-index guard value to conn (design 310 §4.1 — a family root’s binding set growing; see ConnTable::add_guard_value). Required, not defaulted: a decorator that forgot to forward it would leave the family root unindexed and silently drop its deltas.
Source§

fn remove_guard_value(&self, conn: ConnId, value: &OwnedValue)

Remove one dynamic guard value added with add_guard_value.

Auto Trait Implementations§

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.