Skip to content

Exploration: batches as data — Batch<T, B> { desc, inner: Option<B> } - #842

Open
frankmcsherry wants to merge 1 commit into
merger-into-spinefrom
batch-as-struct
Open

Exploration: batches as data — Batch<T, B> { desc, inner: Option<B> }#842
frankmcsherry wants to merge 1 commit into
merger-into-spinefrom
batch-as-struct

Conversation

@frankmcsherry

@frankmcsherry frankmcsherry commented Aug 21, 2026

Copy link
Copy Markdown
Member

Replaces the BatchReader and Batch traits with a struct: a batch is a description plus an optional payload, absent exactly when there are no updates.

pub struct Batch<T, B> {
    pub desc: Description<T>,
    pub inner: Option<B>,
}

TraceReader gains type Payload (batches are BatchOf<Tr>); reading a payload remains the Navigable capability; merging and sizing are the fueled spine's opinions (SpinePayload, with Merger and len). Consequences:

  • Empty batches are constructible by anyone; the minting obligations on batch types (empty) disappear.
  • Rc/Arc sharing is a payload type parameter; the forwarding-impl family (RcBuilder, batch blankets) is deleted.
  • The spine composes merge result descriptions itself; payload mergers are description-free, and a fully cancelled merge records an absent payload.
  • Join/reduce/half-join tactics take payloads and an explicit time; drivers keep descriptions for frontier accounting.

Stacked on #841. Net −115 lines over 40 files; all workspace tests pass.

🤖 Generated with Claude Code

An exploratory replacement of the BatchReader and Batch traits with a
concrete struct: a batch is a Description plus an optional payload,
absent exactly when there are no updates. Payloads are unconstrained;
reading them is the Navigable capability, and everything else is the
business of whichever harness holds them.

Consequences, in rough order of significance:

* Empty batches are constructible by anyone (a description with no
  payload): Batch::empty is a constructor, not a capability, and the
  minting question (TraceWriter::seal, Spine::close) dissolves.
* Rc sharing is a payload type parameter, not a forwarding-impl family:
  rc_blanket_impls shrinks to the Navigable/cursor forwarding, and
  RcBuilder disappears (builders emit Rc payloads directly). External
  Arc newtypes would need no batch impls at all.
* Description algebra hoists out of the payload mergers into the spine:
  MergeState computes each merge result's description (adjacent lower/
  upper, sinces joined with the compaction frontier), and mergers become
  pure payload mergers handed a since. A merged payload that cancels
  entirely becomes an absent payload.
* len() leaves the public batch surface: its only consumers were the
  spine's accounting and logging, so it lives on SpinePayload (the
  renamed SpineBatch), alongside the Merger opinion.
* TraceReader grows a Payload associated type; Tr::Batch becomes the
  BatchOf<Tr> alias. The join/reduce/half-join tactics take payloads
  (empty batches have nothing to join) with an explicit time parameter,
  and the drivers keep descriptions for their frontier accounting.

The two kinds of nothing remain deliberately distinct in the spine:
MergeState::Single(None) is structural fuel bookkeeping with no
description at all; Batch { inner: None } is a recorded empty interval.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@frankmcsherry
frankmcsherry marked this pull request as ready for review August 22, 2026 01:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant