Rindle docs and package mapSkip to main content

Module batch_delta

Module batch_delta 

Source
Expand description

The in-memory batch delta (designs/306-BATCH-OVERLAY-DESIGN.md §4, impl plan §3): a per-TableSource fold of the current transaction’s SourceChanges, standing in for the throwaway derivation writes the historical write-then-abort path performed (deleted with 306 S5). During a derivation, change k+1 must read a base state that already includes changes 1..k; this structure holds exactly that divergence from the pinned base snapshot, so the derivation connection can stay read-only.

Three parts, each a [rindle::btree::BTree] (the engine’s own COW B+tree, reused as-is so the delta inherits the already-fuzzed compare_rows ordering — plan §3.5):

  • touched — every pk the batch touched (present OR removed), keyed under the pk sort. A base row whose pk is here is suppressed from the scan: its authoritative content now lives in primary, or nowhere if the batch removed it.
  • primary — the current derived content of each touched-and-present pk.
  • secondary — the same rows under each index sort a fetch has asked for, created lazily by BatchDelta::rows_for_fetch and maintained eagerly by BatchDelta::apply for the rest of the transaction (plan §3.3).

The delta is shared, not forked: TableSource::fork clones the Rc<BatchDelta> because the delta models storage, which forks share (plan D1). Range reads vend the tree’s owning [BTreeCursor] (an Rc<BNode> spine — the OQ-1 design), constructed under a momentary RefCell borrow, so no borrow is ever held across a vend (plan §3.4 as amended 2026-08-10: the original materialize-to-Vec rule assumed a borrowing cursor and cost O(|delta|) per fetch — O(N²) per batch under per-change ordered re-fetches). A later apply cannot invalidate an in-flight stream either way: it runs at write-after-drain (the same quiet point write_change occupied, with the in-flight change carried by the push overlay), and if a cursor ever were alive, Rc::make_mut path-copies around every node it pins, leaving the cursor its as-of-fetch snapshot.

Structs§

BatchDelta
The per-source batch delta. Interior-RefCell so one Rc<BatchDelta> can be shared between a TableSource, its forks, and the engine that drives the lifecycle (plan D1 — the same idiom as cursors_open/fetch_error).
DeltaBudget
The derivation memory budget (design 306 D4) — what bounds a batch delta, in place of a row count.
DeltaRows
The lazily-pulled delta side of one fetch (BatchDelta::rows_for_fetch): the owning [BTreeCursor] plus the request’s narrowing, applied per pull — constraint group-break, multi-constraint any, then the predicate (arbitrary user-compiled code, safe to run here because no RefCell borrow is held; the same guarantee materializing used to buy, now free).

Enums§

DeltaLookup
What the delta knows about a primary key (BatchDelta::lookup_pk).

Constants§

DEFAULT_MAX_DELTA_BYTES
D4’s default derivation memory budget: 256 MiB of accounted delta (see DeltaBudget), shared by every table a transaction touches. High enough that no OLTP transaction or existing test fires it; a bulk load that does trips [RindleError::DeltaOverflow] — the load-shed signal (the host commits the data and re-hydrates the affected queries) — instead of an OOM. The spill (design §7 / plan S6) lifts it later.