Sign in

    differential

    Experimental Differential Dataflow port for MoonBit; upstream runtime compatibility is incomplete

    Download zip
    Author
    Version
    0.1.0
    License
    MIT
    Last updated
    12 hours ago
    Downloads
    2

    #Differential Dataflow for MoonBit — work in progress

    The target is full upstream compatibility with pinned Rust Differential Dataflow and its Timely runtime. This repository is not a completed port or a production release. COMPATIBILITY.md tracks the remaining work; UPSTREAM.md pins both reference checkouts.

    The implemented foundations currently run on JavaScript, native, Wasm, and Wasm GC:

    • Timestamp lattices, product partial orders, antichains, and counted frontiers.
    • Counted cyclic progress, nested feedback loops, custom timestamp refinements and identity regions.
    • Output capabilities, custom unary operators, and frontier notifications.
    • Signed and presence-only differences and generic update consolidation.
    • Sealed trace batches, logical/physical compaction, and snapshot cursors.
    • Buffered input sessions, cooperative workers, progress probes, and fanout.
    • Worker groups with keyed exchange, global progress, and nested peer iteration.
    • Map, flat-map, filter, explode, negate, concat, and consolidation.
    • Weighted incremental joins, semijoins, and antijoins, including retractions.
    • Grouped reduction, count, threshold, and distinct with synthetic partial-order timestamps.
    • Shared arrangements and independent trace readers, live imports, historical lookups, and total-order upserts with upstream tie-breaking.
    • Capture/replay with duplicate suppression, out-of-order messages, counted progress, retryable writers and externally activated sources.
    • Incremental BFS distances, minimum-label propagation, strongly connected component edges, bidirectional shortest-path queries, and sequential neighbor-state updates.
    • Exclusive prefix sums at sparse 64-bit positions, with independent keys and dynamic queries.
    • Stable identifier assignment with iterative collision repair and Rust-compatible FNV encodings.

    #Installation

    Version 0.1.0 is an experimental checkpoint. The compatibility gaps below remain open; publishing this package does not mark the full port complete.

    moon add bobzhang/differential@0.1.0

    #Example: totals that change when prices change

    ///|
    test "reprice existing orders incrementally" {
    let worker = @differential.Worker()
    let (orders, order_stream) : (
    @differential.InputSession[(Int32, String), Int64, Int64],
    @differential.Collection[(Int32, String), Int64, Int64],
    ) = worker.input(0)
    let (prices, price_stream) : (
    @differential.InputSession[(Int32, Int64), Int64, Int64],
    @differential.Collection[(Int32, Int64), Int64, Int64],
    ) = worker.input(0)
    let changes = []
    let probe = order_stream
    .join_map(price_stream, fn(_, customer, price) { (customer, price) }, multiply=fn(
    quantity,
    present,
    ) {
    quantity * present
    })
    .reduce(fn(_, values) {
    let mut total = 0L
    for (price, quantity) in values {
    total += price * quantity
    }
    [(total, 1L)]
    })
    .inspect(fn(data, time, diff) { changes.push((data, time, diff)) })
    orders.update((1, "Alice"), 3)
    prices.insert((1, 7))
    orders.advance_to(1)
    prices.advance_to(1)
    orders.flush()
    prices.flush()
    assert_true(worker.run() is Quiescent(_))
    prices.remove((1, 7))
    prices.insert((1, 9))
    orders.close()
    prices.close()
    assert_true(worker.run() is Quiescent(_))
    assert_true(probe.done())
    assert_eq(changes, [
    (("Alice", 21L), 0L, 1L),
    (("Alice", 21L), 1L, -1L),
    (("Alice", 27L), 1L, 1L),
    ])
    worker.dispose()
    }

    #Example: incremental fixed points

    ///|
    test "fixed point updates after a root changes" {
    let worker = @differential.Worker()
    let scope = worker.scope(0L, @differential.SummaryDomain::int64())
    let (input, roots) : (
    @differential.InputSession[Int32, Int64, Int64],
    @differential.Collection[Int32, Int64, Int64],
    ) = scope.input()
    let reachable = scope.iterate(roots, fn(_, values) {
    values
    .concat(
    values.flat_map(fn(node) { if node < 5 { [node + 1] } else { [] } }),
    )
    .distinct()
    })
    let counts : Map[Int32, Int64] = Map([])
    let probe = reachable.inspect(fn(node, _, diff) {
    counts[node] = counts.get(node).unwrap_or(0) + diff
    })
    input.insert(2)
    input.advance_to(1)
    input.flush()
    assert_true(worker.run() is Quiescent(_))
    assert_true(!probe.less_than(1))
    assert_eq(counts.get(3), Some(1L))
    input.remove(2)
    input.insert(4)
    input.close()
    assert_true(worker.run() is Quiescent(_))
    assert_true(probe.done())
    assert_eq(counts.get(3), Some(0L))
    assert_eq(counts.get(5), Some(1L))
    worker.dispose()
    }

    #Current contracts

    Build each scope graph before running the worker or flushing that scope's input. Fresh scopes can be created between worker runs, including imports of existing live traces; already executed scope graphs remain frozen. advance_to() changes an input's local timestamp; flush() publishes buffered data and progress. Call close() explicitly to release the input capability. run() returning Quiescent means no operator is currently activated; open inputs can still produce more data. Probe frontiers determine whether a timestamp is complete. dispose() releases the worker's registered tasks and invalidates its inputs.

    Custom operators can retain builder.activator() to request a coalesced wakeup, including from their own callback. activate_after(Duration(...)) schedules a local timer using an explicit Worker(clock=...) monotonic host clock; zero delay needs no clock. The host calls step()/run() and can use next_activation() to choose its next wakeup. Quiescent does not wait for future timers. Handles become inert on retirement or disposal. Thread-safe cross-thread activators are not implemented.

    builder.build_reschedule(...) accepts a callback returning whether external work is still unfinished. Returning true retains the operator but does not queue another invocation: use its activator for that. Once it returns false, all input records and final frontiers have been consumed, and output capabilities are released, the worker drops the callback. Both builder methods accept on_shutdown=... for explicit resource cleanup, called exactly once on completion or worker disposal. Scheduling may coalesce progress wakeups differently from Rust; invocation counts are not a portable contract.

    WorkerGroup(peers) coordinates workers in one process with globally counted progress and keyed exchange. It executes cooperatively on one thread; it does not provide shared-memory parallel threads. Build identical operator graphs on each peer (including newly added scope groups), and use ScopeGroup.exchange to colocate equal keys before keyed operations. ScopeGroup.iterate coordinates nested progress and exchange. Dispose the entire group with group.dispose().

    ClusterWorker runs independent processes using ordered all-gather rounds. DistributedScope.exchange serializes updates and tracks records in transit; DistributedScope.iterate coordinates nested fixed points across processes. The native transport package supplies TcpTransport for POSIX hosts. All peers must build identical graphs, use compatible codecs, and call run() with the same round bound. New scopes must be added in the same order between runs on all peers; their graph manifests are checked before processing them. Release the worker and close the transport separately. Transport errors terminate the runtime. This currently uses synchronous barriers and its own wire protocol. See validation/cluster for an executable two-process example.

    scale_pair, scale_triple and scale_quad apply independent multiplication callbacks to tuple fields; result types may differ by field. scale_unit covers the empty tuple, and singleton/vector differences provide scale methods.

    Tuples, timestamps, and weights must be immutable. Comparison and algebra traits must obey their mathematical laws. Callbacks must be deterministic and must not re-enter the worker or mutate the graph. Signed weights use MoonBit integer arithmetic; applications are responsible for avoiding unwanted overflow.

    Int8, Int128, and UInt128 cover integer widths absent from native MoonBit types. Wrapping preserves explicit signed wrapping types; SingletonDiff adapts Rust one-element tuples. Graph propagation and SCC accept any Ring difference, which supplies multiplication and one in addition to Abelian addition.

    join_map accepts explicit weight multiplication so different input and output weight types can be used without Rust associated types. antijoin implements weighted subtraction; its key input must have weights zero or one for set-style exclusion. distinct represents any nonzero accumulated weight, including a negative weight, as one occurrence.

    Reduction enumerates the finite join-closure of retained timestamps. It compacts input and output history at arbitrary antichain frontiers and releases canceled keys. Retention tests cover 20,000 total-order and 5,000 incomparable-frontier epochs. Timestamp closure can still grow exponentially for some lattices; further incremental optimization remains necessary.

    Batcher(minimum) consumes chunks, merges sorted chains, and seals intervals at arbitrary antichains. BatchBuilder consumes ordered chunks into immutable batches. Batch.begin_merge creates a BatchMerger whose work(fuel) advances by complete data groups; is_complete() and done() finish the result. Fuel counts input updates and may overshoot by one group, a conservative adaptation of Rust's output-based accounting. Spine(minimum) uses these primitives for bounded maintenance and configurable idle exertion. shared_spine(minimum) adds independently pinned readers; collection.arrange_by_key(fueled=true) selects that backend for arrangements. The default arrangement backend retains eager compaction for existing callers.

    ColumnarBatch(updates, lower=..., upper=...) stores keys, values, timestamps and weights in separate immutable arrays; offset tables share repeated keys and values. batch() shares those columns with the normal trace/cursor APIs. Use arrange_by_key(columnar=true, fueled=true) (or arrange_by_self) to retain that layout through live arrangements and compaction. Storage counts describe entries, not measured bytes. The current merge/compaction path uses temporary row groups; upstream's trie-native chunk transducers and binary codecs remain pending.

    SpillPolicy(budget_records, store=..., codec=..., chunk_size=...) pages sealed batches through a pluggable BytesStore. Use batch.spill(policy) or pass spill=policy to an arrangement. Compaction and merging retain the spill policy. The high-water-mark resident budget is cumulative, matching upstream: dropping old batches does not replenish it. Each reader caches one decoded page; builders and mergers still use temporary rows, so this is not a total process-memory cap. Payload checksums reject changed storage before decoding. stats() reports stored/fetched chunks, records and bytes.

    The native spill_file package supplies SpillFile().store(), backed by an anonymous temporary file. Page handles retain the file; optional close() invalidates outstanding handles. This is temporary storage, not durable replay. Codecs are explicit; the supplied JSON codec preserves 64-bit values but does not implement Rust's columnar binary format.

    Cursor merges retained batch views without copying stored update history. Times are visited per batch; callers consolidate them when needed.

    Arranged.join and Arranged.join_map share existing sorted batch indexes, using binary key lookup and independent compaction capabilities. Multiple joins reuse one arrangement without copying its history. Arranged.reduce also reuses shared key ranges and caches unchanged-key corrections. Release the arrangement handle after building consumers; the consumers retain their own readers until completion. Arranged.enter and ArrangementView.enter_refined retain the original index across nested scopes. TraceReader adapts timestamps and compaction capabilities without copying stored batches; BatchView maps immutable batches lazily. BatchView.frontier and TraceReader.frontier advance visible times by a since frontier and suppress updates at or beyond an until frontier. As in Rust, they preserve batch metadata and cursor keys even when all times for a key are hidden. ArrangementView.enter_at assigns inner times from the data, with an explicit conservative inverse for compaction. TraceReader.import_into supports these views for both retained history and future sealed batches. Views and readers own independent capabilities and require release(). Scope.bfs_arranged, Scope.propagate_core, and Scope.bidijkstra_arranged accept these views, allowing graph algorithms to share edge indexes. Collection convenience methods build those indexes once and delegate to the same algorithms.

    Use worker.scope(minimum, domain) for counted progress and cyclic graphs; worker.input(initial) remains available for acyclic pipelines. Scope boundaries share one progress calculation seeded by real capabilities and queued records, so an empty nested feedback cycle cannot sustain its own progress. Scope minimums must be lower bounds of all timestamps supplied in that domain. Individual feedback edges may move time backward, provided complete cycles have convergent reachability summaries and the domain laws hold. iterate does not insert consolidation: finish the loop body with distinct, reduce, or consolidate to dissipate canceling differences, as in upstream.

    Capabilities and trace readers use explicit release() in place of Rust Drop. Cloning creates independent ownership; a plain MoonBit assignment aliases the same handle. Notification queues and capability sets transfer inserted handles. Custom unary data callbacks borrow their capability: clone it to retain it. scope.operator() builds heterogeneous multi-input/output operators. Its input capabilities are borrowed; cap.delayed(output, time) creates an owned output capability only when the declared connection summaries permit that timestamp. Empty summary sets disconnect a port pair. Release every initial output capability received by builder.build when it is no longer needed. Worker disposal cancels imports and lookups, unregisters listeners, and clears scoped progress and queued records.

    Ordering follows MoonBit's Compare implementation. In particular, built-in String comparison is length-first, unlike Rust's lexical string order. Use a custom ordered key/value type when lexical ordering matters (for example upsert ties or minimum-value reductions).

    Trace snapshot(time) requires a complete timestamp at or beyond the logical compaction frontier. Physical compaction can remove batch cuts; cursor_through then returns None. Cursors snapshot their records and survive later compaction.

    ScopeGroup::replay_from and DistributedScope::replay_from reconstruct one captured collection from messages arriving at any peer. Duplicate messages across peers are counted once globally; output goes to hash(data) % peers. These adapters partition record deduplication and timestamp counts, then exchange compact frontiers. time_hash controls count sharding; group replay defaults to peer zero, process replay hashes the timestamp codec. Source replay emits records eagerly and rejects different weights for the same data/time. The standalone Replayer waits for sealed intervals. A paused source keeps progress open; wake its handle when messages arrive and cancel every peer to abandon a replay.

    Arrangement join and join_map accept fuel (default 100,000). A turn performs at most that many cursor/emission steps before yielding. Pending work retains immutable batch views and timestamp capabilities, so probes cannot report its results complete prematurely. Empty historical intervals do not hold old times.

    TcpTransport.start_exchange(value) and poll_exchange() provide nonblocking round I/O for host event loops. A pending poll returns None; a completed poll returns peer-ordered values. Each peer advances at most 64 KiB of payload per poll, with frame bounds and deadlines. Connection setup and handshake remain synchronous. Do not overlap exchanges or mix a pending asynchronous exchange with exchange. Native validation checks host control before peer input, fragmented frames, 11 failure cases, and repeated large exchanges across two/three peers.

    For host-polled cluster execution, construct AsyncExchange(start=..., poll=...) and pass it as ClusterWorker(..., async_exchange=adapter). Bind these callbacks to the transport's start_exchange and poll_exchange. cluster.poll() reports Pending, Progress, or Quiescent; schedule a later host callback for Pending. run() also yields as StepLimit when I/O is pending. It freezes the submitted graph and keeps frontiers open until the complete peer response is applied. Build graphs and submit input epochs before driving all peers to quiescence. This removes blocking waits from round I/O; progress still uses collective rounds, not decentralized peer-to-peer scheduling. Native comparisons repeat all six workload families through the asynchronous adapter (784 epochs).

    #Dataflow lifecycle

    Each root worker.scope(...) gets a monotone dataflow_index; nested scopes and regions share it. next_dataflow_index, installed_dataflows, and has_dataflows inspect this lifecycle. worker.drop_dataflow(id) cancels a local dataflow and all its nested work without disposing the worker. It drops queued records, invalidates scoped output capabilities, runs operator shutdown callbacks once, and closes trace writers so independent imports can finish. Externally owned trace readers remain usable. Later flush/close calls on cancelled inputs are ignored. As in pinned Timely, cancelled probes retain their last observed frontier: cancellation does not certify that queued records were processed. WorkerGroup.drop_dataflow(id) cancels corresponding roots across cooperative peers. ClusterWorker.drop_dataflow(id) requests collective cancellation: any peer can request it, and the next run round applies it everywhere before record delivery. All peers must continue calling run. This takes effect at the round boundary; work already processed remains observable. Cluster protocol version 3 carries cancellation requests alongside progress and completion votes.

    #Runnable upstream algorithms

    Run moon run examples/showcase --target js (or --target native) to see integer PageRank, degree histograms, and item recommendations update after graph insertions and removals. Each printed row contains the completed epoch followed by the three accumulated results. These are reusable functions in bobzhang/differential/examples/algorithms.

    PageRank retains upstream's six-million initial and one-million reset weights, with a positive iteration bound. Recommendations assume set-valued user/item interactions and return exact (intersection, union) Jaccard fractions; upstream's final floating score is an intentional presentation adaptation. Users with at least max_interactions interactions are excluded, and scores must exceed 0.05. The randomized oracle compares all three algorithms with pinned Rust and full recomputation over 384 epochs, including empty input and complete retractions.

    #Persistent capture

    The native bobzhang/differential/capture_journal package stores capture messages in an exclusively created POSIX file. Use CaptureMessage::codec with explicit data/time/difference codecs, CaptureJournal::create(path), and journal.append(message, codec). Each append fsyncs; creation also syncs the containing directory. To replay, open a reader with CaptureJournal::open(path) and call next(codec) from Scope::replay_from. Wake its handle when new bytes arrive. EOF or an incomplete last frame means temporarily unavailable; only terminal capture progress means completion. Complete corrupt frames raise JournalError and poison the reader. Call close explicitly to report close errors. Automatic writer recovery is not provided. The versioned JSON/frame encoding is independent of Rust serde.

    #Custom trace storage

    Collection.arrange_with(factory) accepts a TraceBackend with a reader, batch insertion and closure callbacks, and an optional batch builder. BatchView adapts an immutable indexed layout without eagerly copying its rows. TraceReader adapts clean batch cuts, compaction capabilities, cloning, and live subscriptions. The resulting ArrangementView supports shared joins, reductions, nested scopes, and imported queries through the same operators as built-in storage.

    A backend must retain immutable batches while readers use them, clone independent compaction pins, and seal its upper frontier when closed. Operator cancellation closes the writer, allowing surviving imports to finish. The black-box tests in trace_adapters_test.mbt implement an independent four-column backend and exercise these ownership and progress requirements.

    #Message times and record times

    A data message carries a capability time; each (data, time, difference) record inside it may have a later logical time. InputSession.update_at and Output.send_at preserve that distinction through mapping, nested scopes, feedback, and local or process exchange. Progress counts messages at their capability times, so future records do not hide unfinished earlier work.

    • inspect_batch observes the capability time and a copied record array; inspect_container also observes frontier changes and forwards the stream.
    • results_in(step, domain) changes logical record times and drops overflows, while retaining the original message capability.
    • delay(advance) changes both times and holds messages until the input frontier passes their delayed capability. The function must be pure, monotone, and only advance times.
    • join_function joins input times with computed row times and applies an explicit weight multiplication callback.
    • consolidate_stream consolidates each message immediately, without waiting for all updates at a logical time.
    • OperatorInput.for_each_batch exposes original messages and borrowed input capabilities; for_each remains a convenience API grouped by record time.

    The cluster protocol is now version 4 because routed messages include capability timestamps. All participating workers must use the same library version.

    #Min-plus shortest paths

    examples/algorithms.monoid_bfs ports upstream's semigroup shortest-path example. MinSum combines alternative routes by minimum and extends routes by adding their lengths. Adding edges, lowering edge weights, or adding roots propagates improved distances through a feedback loop; zero-weight cycles converge. These weights do not support retractions, so deleting edges requires the ordinary signed-weight formulation. validation/bridge/monoid_bfs.mbt demonstrates incremental updates.

    Scope.variable(step) now supports weights without negation. Only Scope.variable_from(source, step) requires Abelian, because it must subtract the initially supplied source. This matches upstream's constructor distinction.

    #Reducers with explicit corrections

    Collection.reduce_core, Arranged.reduce_core, and ArrangementView.reduce_core receive the key, consolidated input snapshot, and consolidated existing output snapshot. Return the changes to apply to that output. Both snapshots are owned copies; the callback can receive an empty input after a retraction. It is never called with both snapshots empty.

    Unlike reduce, this API accepts output weights that implement only Semigroup. For example, a presence-only reducer can emit newly seen values without requiring subtraction or a zero value. The result is an Arranged shared index; use as_collection() for the update stream and release the arrangement when finished. The callback must be deterministic and preserve its reduction invariant after applying corrections, including at joins of incomparable timestamps.

    #Runtime-defined iteration depths

    PointStamp stores a runtime-sized vector of timestamp coordinates. It uses product order, so independent inner iterations can remain incomparable. Trailing minimum coordinates are canonicalized away. SummaryDomain::pointstamp lifts a scalar summary domain; feedback_summary(level, step) advances one coordinate, and Scope.leave_dynamic(collection, level) discards coordinates at and below that one-based level. enter_dynamic is an identity operation, as upstream.

    Use these types inside a normal product scope when the number of nested loops is known only at runtime. WireCodec::pointstamp and pointstamp_summary support the same scopes across process workers. The validation/bridge/pointstamp.mbt and validation/cluster/pointstamp.mbt fixtures demonstrate local and distributed fixed points with runtime-selected depths and input retractions.

    #Validation

    moon fmt --check moon check --target all --warn-list +unnecessary_annotation --deny-warn moon test --target all # Restore pinned references using UPSTREAM.md first: python3 validation/compare.py python3 validation/cluster_compare.py python3 validation/transport_failures.py python3 validation/journal_check.py # Optional Clang ASan/LSan validation: python3 validation/sanitize_cluster.py

    The pinned Rust comparisons cover:

    • 10,240 frontier/compaction rounds and 1,024 live weighted join epochs.
    • 128 product-time reduction cases, with 3,200 independent snapshot queries.
    • 768 streamed reduction epochs with independently advanced antichain capabilities.
    • 256 feedback epochs and 256 nested fixed-point epochs with a cyclic graph BFS oracle.
    • 1,024 shared-arrangement epochs with independent reader compaction.
    • 8,192 upsert records, including equal-time conflicts and deletion.
    • 256 reordered/duplicated capture-replay cases, comparing exact progress transitions.
    • 128 eager source cases against Rust, with records available before sealed progress.
    • 1,536 activated capture/replay epochs with update retries, duplicate messages, progress arriving before data, and an independent accumulated-state oracle.
    • 512 partitioned join epochs against Rust running two workers.
    • 128 distributed replay epochs in two/three native processes against Rust running three workers, including duplicates across peers and delayed data.
    • 128 TCP process join epochs and 128 fixed-point epochs with one/two nested loops and two/three peers.
    • 192 dynamic graph epochs comparing BFS, label propagation, SCC edge weights, and scheduled variants.
    • 2,048 cases for 128-bit wrapping arithmetic, checked overflow, and Duration carries.
    • 192 prefix-sum epochs with sparse positions, data/query retractions and multiplicities.
    • 384 identifier epochs with forced collisions, winner deletions and FNV encoding checks.
    • 192 bidirectional search/sequential-update epochs with independent graph recomputation.

    Local retention tests exercise 20,000 total-order and 5,000 antichain reduction epochs, 2,000 shared-index join epochs, 2,000 feedback epochs, 2,000 shared-trace epochs, 10,000 replay intervals, and 1,000 exchange epochs. Tests run on native, JavaScript, Wasm, and Wasm GC. The CI workflow repeats backend tests on Linux and macOS and runs the Rust oracle separately; it has not yet run on GitHub for this unfinished port. Results validate these components, not full upstream compatibility. See validation/results.json.

    MIT licensed; both upstream notices are retained. Module: bobzhang/differential.

    Collection utilities include map_in_place, concatenate, assert_eq and assert_empty. Use Probe() with collection.probe_with(handle) to wait on several collections through one combined progress frontier.

    To observe arrangement growth and reader retention, insert a Logger[DifferentialEvent] into worker.differential_logs() under "differential/arrange" before building the graph. Its callback receives monotone wall-clock timestamps and owned event batches. Call the registry's flush() from your host event loop. Trace events include sealed batch sizes, merge start/completion, retained-batch release, pending record deltas and reader shares. Supply a monotone clock to the logger; managed-memory byte counts are reported as unavailable rather than estimated.

    UpdatesTyped exposes columnar key/value/time/difference tries independently of trace batches. It supports raw grouped columns, streaming consolidation, partial merges, split/meld, and frontier extraction. Canonical chunks become immutable indexed batches without flattening through chunk.batch(description); they work with the same trace, cursor, import and spill APIs.

    For Rust columnar storage interoperability, construct ColumnarCodec(key, value,time, difference) from ColumnCodec schemas. Its encoding matches the pinned Rust Updates<U> representation byte for byte; decoding returns a validated owned trie. Schemas compose for products, pairs, vectors, strings and other standard types, or can be supplied for application-specific column layouts.

    Use columnar_codec.spill_policy(budget, store=..., chunk_size=...) to page arrangement storage in the same Rust columnar format. SpillPolicy.binary accepts other application-defined byte formats; the existing JSON constructor remains available. Both policies preserve lazy page loading and checksum validation.

    Abelian

    pub(open) trait Abelian : Monoid {
    fn negate(Self) -> Self
    }

    impl Abelian for Unit
    impl Abelian for Int
    impl Abelian for Int16
    impl Abelian for Int64
    impl Abelian for Tuple2[A, B]
    impl Abelian for Tuple3[A, B, C]
    impl Abelian for Tuple4[A, B, C, D]

    Lattice

    pub(open) trait Lattice : Compare {
    fn less_equal(Self, Self) -> Bool
    fn join(Self, Self) -> Self
    fn meet(Self, Self) -> Self
    }

    A partial order with least upper bounds and greatest lower bounds. Compare is a consistent total extension used only for storage order.
    impl Lattice for Unit
    impl Lattice for Byte
    impl Lattice for Int
    impl Lattice for Int16
    impl Lattice for Int64
    impl Lattice for UInt
    impl Lattice for UInt16
    impl Lattice for UInt64

    Monoid

    pub(open) trait Monoid : Semigroup {
    fn zero() -> Self
    }

    impl Monoid for Unit
    impl Monoid for Byte
    impl Monoid for Int
    impl Monoid for Int16
    impl Monoid for Int64
    impl Monoid for UInt
    impl Monoid for UInt16
    impl Monoid for UInt64
    impl Monoid for Tuple2[A, B]
    impl Monoid for Tuple3[A, B, C]
    impl Monoid for Tuple4[A, B, C, D]

    Ring

    pub(open) trait Ring : Abelian {
    fn one() -> Self
    fn multiply(Self, Self) -> Self
    }

    An Abelian difference with a multiplicative identity and closed multiplication. This packages upstream's Abelian + Multiply + From requirements for generic graph algorithms. Arithmetic must obey the ring laws.
    impl Ring for Int
    impl Ring for Int16
    impl Ring for Int64

    RustHash

    pub(open) trait RustHash {
    fn hash_into(Self, FnvHasher) -> Unit
    }

    Rust Hash byte encoding for identifier interoperability. Custom records can implement this trait by hashing their fields in declaration order.
    impl RustHash for Unit
    impl RustHash for Bool
    impl RustHash for Byte
    impl RustHash for Char
    impl RustHash for Int
    impl RustHash for Int16
    impl RustHash for Int64
    impl RustHash for UInt
    impl RustHash for UInt16
    impl RustHash for UInt64
    impl RustHash for String
    impl RustHash for Option[T]
    impl RustHash for Bytes
    impl RustHash for Array[T]
    impl RustHash for Tuple2[A, B]
    impl RustHash for Tuple3[A, B, C]
    impl RustHash for Tuple4[A, B, C, D]

    Semigroup

    pub(open) trait Semigroup {
    fn plus(Self, Self) -> Self
    fn is_zero(Self) -> Bool
    }

    Associative, commutative accumulation and an additive-identity test.
    impl Semigroup for Unit
    impl Semigroup for Byte
    impl Semigroup for Int
    impl Semigroup for Int16
    impl Semigroup for Int64
    impl Semigroup for UInt
    impl Semigroup for UInt16
    impl Semigroup for UInt64
    impl Semigroup for Tuple2[A, B]
    impl Semigroup for Tuple3[A, B, C]
    impl Semigroup for Tuple4[A, B, C, D]

    Timestamp

    pub(open) trait Timestamp : Lattice {
    fn minimum() -> Self
    }

    A timestamp lattice with a unique global minimum. SummaryDomain carries the associated path-summary operations separately, rather than as a Rust type.
    impl Timestamp for Unit
    impl Timestamp for Byte
    impl Timestamp for Int
    impl Timestamp for Int16
    impl Timestamp for Int64
    impl Timestamp for UInt
    impl Timestamp for UInt16
    impl Timestamp for UInt64

    TotalOrder

    pub(open) trait TotalOrder : Lattice {
    }

    Marker: the lattice order must agree with Compare's total order.
    impl TotalOrder for Unit
    impl TotalOrder for Byte
    impl TotalOrder for Int
    impl TotalOrder for Int16
    impl TotalOrder for Int64
    impl TotalOrder for UInt

    ClusterError

    pub suberror ClusterError {
    ClusterError(String)
    } derive(
    Debug
    )

    Activator

    pub struct Activator {
    // private fields
    }

    A cloneable local activation handle. It retains the scheduler, not the worker or operator closure. Activations are coalesced until the operator runs.

    Activator::activate

    fn Activator::activate(self : Activator) -> Unit

    Queue a wakeup. A handle retained after worker disposal becomes inert.

    Activator::activate_after

    fn Activator::activate_after(self : Activator, delay : Duration) -> Unit

    Queue a timed wakeup using the worker's supplied monotonic clock. A zero delay is an ordinary activation. The host drives step/run and can use next_activation to decide when to call again; no backend-specific sleep runs.

    Activator::clone

    fn Activator::clone(self : Activator) -> Activator

    Activator::try_activate

    fn Activator::try_activate(self : Activator) -> Bool

    Antichain

    pub struct Antichain[T] {
    // private fields
    }

    Minimal incomparable timestamps; empty means no future times remain.

    Antichain::Antichain

    fn[T : Lattice + Compare + Eq] Antichain::Antichain(elements : Array[T]) -> Antichain[T]

    Antichain::clear

    fn[T] Antichain::clear(self : Antichain[T]) -> Unit

    Antichain::insert

    fn[T : Lattice + Compare + Eq] Antichain::insert(self : Antichain[T], time : T) -> Bool

    Antichain::is_empty

    fn[T] Antichain::is_empty(self : Antichain[T]) -> Bool

    Antichain::join

    fn[T : Lattice + Compare + Eq] Antichain::join(self : Antichain[T], other : Antichain[T]) -> Antichain[T]

    Least upper bound of frontier upsets (their intersection).

    Antichain::less_equal

    fn[T : Lattice + Compare + Eq] Antichain::less_equal(self : Antichain[T], time : T) -> Bool

    Antichain::less_than

    fn[T : Lattice + Compare + Eq] Antichain::less_than(self : Antichain[T], time : T) -> Bool

    Antichain::precedes

    fn[T : Lattice + Compare + Eq] Antichain::precedes(self : Antichain[T], other : Antichain[T]) -> Bool

    True if this frontier is no later than the other frontier.

    Antichain::to_array

    fn[T] Antichain::to_array(self : Antichain[T]) -> Array[T]

    Arranged

    pub struct Arranged[K, V, T, R] {
    // private fields
    }

    A shared, sealed key/value index and its consolidated update stream.

    Arranged::as_collection

    fn[K, V, T, R] Arranged::as_collection(self : Arranged[K, V, T, R]) -> Collection[(K, V), T, R]

    Arranged::enter

    fn[K : Compare + Eq, V : Compare + Eq, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R : Semigroup, S, U] Arranged::enter(self : Arranged[K, V, A, R], nested : NestedScope[A, B, S, U]) -> ArrangementView[K, V, Product[A, B], R]

    Arranged::enter_at

    fn[K : Compare + Eq, V : Compare + Eq, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R : Semigroup, S, U] Arranged::enter_at(self : Arranged[K, V, A, R], nested : NestedScope[A, B, S, U], assign : ((K, V), A) -> B, prior : (Product[A, B]) -> A) -> ArrangementView[K, V, Product[A, B], R]

    Arranged::enter_refined

    fn[K : Compare + Eq, V : Compare + Eq, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R : Semigroup, S, U] Arranged::enter_refined(self : Arranged[K, V, A, R], nested : RefinedScope[A, B, S, U]) -> ArrangementView[K, V, B, R]

    Arranged::join

    fn[K : Compare + Eq, V : Compare + Eq, W : Compare + Eq, T : Lattice + Compare + Eq] Arranged::join(self : Arranged[K, V, T, Int64], other : Arranged[K, W, T, Int64], fuel? : Int) -> Collection[(K, (V, W)), T, Int64]

    Arranged::join_map

    fn[K : Compare + Eq, V : Compare + Eq, W : Compare + Eq, D, T : Lattice + Compare + Eq, R : Semigroup, S : Semigroup, O] Arranged::join_map(self : Arranged[K, V, T, R], other : Arranged[K, W, T, S], logic : (K, V, W) -> D, multiply~ : (R, S) -> O, fuel? : Int) -> Collection[D, T, O]

    Join arrangements through independent readers of shared batch indexes.

    Arranged::reduce

    fn[K : Compare + Hash + Eq, V : Compare + Eq, W : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup, S : Abelian + Monoid + Semigroup] Arranged::reduce(self : Arranged[K, V, T, R], logic : (K, Array[(V, R)]) -> Array[(W, S)]) -> Collection[(K, W), T, S]

    Reduce directly from a shared arrangement. Input history stays in the shared index; per-key state retains only output history and unfinished corrections. Logic is recomputed only for changed keys, and its input is a copied snapshot.

    Arranged::reduce_arranged

    fn[K : Compare + Hash + Eq, V : Compare + Eq, W : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup, S : Abelian + Monoid + Semigroup] Arranged::reduce_arranged(self : Arranged[K, V, T, R], logic : (K, Array[(V, R)]) -> Array[(W, S)]) -> Arranged[K, W, T, S]

    Retain the reduced output as a shared index for downstream joins or reductions.

    Arranged::reduce_core

    fn[K : Compare + Hash + Eq, V : Compare + Eq, W : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup, S : Semigroup] Arranged::reduce_core(self : Arranged[K, V, T, R], logic : (K, Array[(V, R)], Array[(W, S)]) -> Array[(W, S)]) -> Arranged[K, W, T, S]

    Compute semigroup output corrections from a shared arrangement. Input history remains in the shared index; the callback receives sorted snapshot copies.

    Arranged::release

    fn[K : Compare + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Arranged::release(self : Arranged[K, V, T, R]) -> Unit

    Release the arrangement handle's own reader; cloned readers remain valid.

    Arranged::trace

    fn[K, V, T : Lattice + Compare + Eq, R] Arranged::trace(self : Arranged[K, V, T, R]) -> TraceAgent[(K, V), T, R]

    Clone an independent reader capability. Release it explicitly after use.

    Arranged::view

    fn[K : Compare + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Arranged::view(self : Arranged[K, V, T, R]) -> ArrangementView[K, V, T, R]

    ArrangementView

    pub struct ArrangementView[K, V, T, R] {
    // private fields
    }

    An arrangement backed by a retained trace view. Entering a scope adapts batch timestamps lazily and preserves the original index and reader compaction pins.

    ArrangementView::as_collection

    fn[K, V, T, R] ArrangementView::as_collection(self : ArrangementView[K, V, T, R]) -> Collection[(K, V), T, R]

    ArrangementView::enter

    fn[K, V, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R, S, U] ArrangementView::enter(self : ArrangementView[K, V, A, R], nested : NestedScope[A, B, S, U]) -> ArrangementView[K, V, Product[A, B], R]

    ArrangementView::enter_at

    fn[K, V, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R, S, U] ArrangementView::enter_at(self : ArrangementView[K, V, A, R], nested : NestedScope[A, B, S, U], assign : ((K, V), A) -> B, prior : (Product[A, B]) -> A) -> ArrangementView[K, V, Product[A, B], R]

    Enter at a data-dependent inner time while retaining the original index. prior maps inner compaction capabilities conservatively into outer time.

    ArrangementView::enter_refined

    fn[K, V, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R, S, U] ArrangementView::enter_refined(self : ArrangementView[K, V, A, R], nested : RefinedScope[A, B, S, U]) -> ArrangementView[K, V, B, R]

    ArrangementView::join

    fn[K : Compare + Eq, V, W, T : Lattice + Compare + Eq] ArrangementView::join(self : ArrangementView[K, V, T, Int64], other : ArrangementView[K, W, T, Int64], fuel? : Int) -> Collection[(K, (V, W)), T, Int64]

    ArrangementView::join_map

    fn[K : Compare + Eq, V, W, D, T : Lattice + Compare + Eq, R, S, O] ArrangementView::join_map(self : ArrangementView[K, V, T, R], other : ArrangementView[K, W, T, S], logic : (K, V, W) -> D, multiply~ : (R, S) -> O, fuel? : Int) -> Collection[D, T, O]

    Join two arrangements using their shared batch indexes. Each operator owns independent compaction capabilities, but no private copy of either history. Each activation performs at most fuel cursor/emission steps and retains output capabilities until pending work finishes. Build before execution.

    ArrangementView::reduce

    fn[K : Compare + Hash + Eq, V : Compare + Eq, W : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup, S : Abelian + Monoid + Semigroup] ArrangementView::reduce(self : ArrangementView[K, V, T, R], logic : (K, Array[(V, R)]) -> Array[(W, S)]) -> Collection[(K, W), T, S]

    Reduce directly from a shared arrangement. Input history stays in the shared index; per-key state retains only output history and unfinished corrections. Logic is recomputed only for changed keys, and its input is a copied snapshot.

    ArrangementView::reduce_arranged

    fn[K : Compare + Hash + Eq, V : Compare + Eq, W : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup, S : Abelian + Monoid + Semigroup] ArrangementView::reduce_arranged(self : ArrangementView[K, V, T, R], logic : (K, Array[(V, R)]) -> Array[(W, S)]) -> Arranged[K, W, T, S]

    Retain the reduced output as a shared index for downstream joins or reductions.

    ArrangementView::reduce_core

    fn[K : Compare + Hash + Eq, V : Compare + Eq, W : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup, S : Semigroup] ArrangementView::reduce_core(self : ArrangementView[K, V, T, R], logic : (K, Array[(V, R)], Array[(W, S)]) -> Array[(W, S)]) -> Arranged[K, W, T, S]

    Shared-index reduction with explicit correction logic and semigroup outputs.

    ArrangementView::release

    fn[K, V, T, R] ArrangementView::release(self : ArrangementView[K, V, T, R]) -> Unit

    ArrangementView::trace

    fn[K, V, T, R] ArrangementView::trace(self : ArrangementView[K, V, T, R]) -> TraceReader[(K, V), T, R]

    AsyncExchange

    pub struct AsyncExchange {
    // private fields
    }

    Nonblocking host adapter. start submits one immutable round payload; poll returns None while pending or one peer-ordered response. Only one round is outstanding. Both callbacks run on the owning worker thread.

    AsyncExchange::AsyncExchange

    fn AsyncExchange::AsyncExchange(start~ : (String) -> Unit raise, poll~ : () -> Array[String]? raise) -> AsyncExchange

    Batch

    pub struct Batch[D, T, R] {
    // private fields
    }

    Immutable sorted updates with a sealed timestamp interval.

    Batch::Batch

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Batch::Batch(updates : Array[(D, T, R)], lower~ : Antichain[T], upper~ : Antichain[T]) -> Batch[D, T, R]

    Batch::begin_merge

    fn[D, T : Lattice + Compare + Eq, R] Batch::begin_merge(self : Batch[D, T, R], other : Batch[D, T, R], since : Antichain[T]) -> BatchMerger[D, T, R]

    Batch::columnar

    fn[K : Eq, V : Eq, T, R] Batch::columnar(self : Batch[(K, V), T, R]) -> ColumnarBatch[K, V, T, R]

    Convert a batch without changing its interval or compaction frontier.

    Batch::compact

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Batch::compact(self : Batch[D, T, R], since : Antichain[T]) -> Batch[D, T, R]

    Batch::description

    fn[D, T, R] Batch::description(self : Batch[D, T, R]) -> Description[T]

    Batch::empty

    fn[D, T : Lattice + Compare + Eq, R] Batch::empty(lower~ : Antichain[T], upper~ : Antichain[T]) -> Batch[D, T, R]

    Batch::for_key

    fn[K : Compare + Eq, V, T, R] Batch::for_key(self : Batch[(K, V), T, R], key : K, visit : (V, T, R) -> Unit) -> Unit

    Visit a key's contiguous range in the immutable sorted batch. This searches shared storage without materializing a cursor or copying unrelated keys.

    Batch::is_empty

    fn[D, T, R] Batch::is_empty(self : Batch[D, T, R]) -> Bool

    Batch::length

    fn[D, T, R] Batch::length(self : Batch[D, T, R]) -> Int

    Batch::merge

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Batch::merge(self : Batch[D, T, R], other : Batch[D, T, R], since : Antichain[T]) -> Batch[D, T, R]

    Batch::spill

    fn[D, T, R] Batch::spill(self : Batch[D, T, R], policy : SpillPolicy[D, T, R]) -> Batch[D, T, R]

    Page a sealed batch using this policy. Repeated calls on a paged batch are idempotent. Compaction and merges continue to use its original spill policy.

    Batch::to_array

    fn[D, T, R] Batch::to_array(self : Batch[D, T, R]) -> Array[(D, T, R)]

    Batch::view

    fn[D, T, R] Batch::view(self : Batch[D, T, R]) -> BatchView[D, T, R]

    BatchBuilder

    pub struct BatchBuilder[D, T, R] {
    // private fields
    }

    Build an immutable batch from sorted update chunks. push consumes its chunk; done consumes the builder. Equal adjacent updates are consolidated.

    BatchBuilder::BatchBuilder

    fn[D, T, R] BatchBuilder::BatchBuilder(capacity? : Int) -> BatchBuilder[D, T, R]

    BatchBuilder::done

    fn[D, T, R] BatchBuilder::done(self : BatchBuilder[D, T, R], description : Description[T]) -> Batch[D, T, R]

    Description may specify compaction; compacted records can exceed its upper.

    BatchBuilder::push

    fn[D : Compare + Eq, T : Compare + Eq, R : Semigroup] BatchBuilder::push(self : BatchBuilder[D, T, R], chunk : Array[(D, T, R)]) -> Unit

    BatchBuilder::seal

    fn[D : Compare + Eq, T : Compare + Eq, R : Semigroup] BatchBuilder::seal(chain : Array[Array[(D, T, R)]], description : Description[T]) -> Batch[D, T, R]

    BatchEvent

    pub(all) struct BatchEvent {
    operator : Int
    length : Int
    } derive(Eq,
    Debug
    )

    BatchEvent::equal

    fn BatchEvent::equal(BatchEvent, BatchEvent) -> Bool

    BatchEvent::not_equal

    fn BatchEvent::not_equal(x : BatchEvent, y : BatchEvent) -> Bool

    BatchMerger

    pub struct BatchMerger[D, T, R] {
    // private fields
    }

    Incrementally merge consecutive immutable batches. One work unit consumes an input update; a call may exceed its fuel to complete one data record's group. This accounting is conservative compared with upstream's output-based fuel.

    BatchMerger::BatchMerger

    fn[D, T : Lattice + Compare + Eq, R] BatchMerger::BatchMerger(left : Batch[D, T, R], right : Batch[D, T, R], since : Antichain[T]) -> BatchMerger[D, T, R]

    BatchMerger::done

    fn[D, T, R] BatchMerger::done(self : BatchMerger[D, T, R]) -> Batch[D, T, R]

    BatchMerger::is_complete

    fn[D, T, R] BatchMerger::is_complete(self : BatchMerger[D, T, R]) -> Bool

    BatchMerger::work

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] BatchMerger::work(self : BatchMerger[D, T, R], fuel : Int) -> Int

    Return unspent fuel. A positive remainder guarantees completion. A zero or negative remainder may also be complete; is_complete disambiguates this case.

    BatchView

    pub struct BatchView[D, T, R] {
    // private fields
    }

    A lazy immutable batch view. Timestamp adaptation retains the backing batch; it does not copy or rebuild the stored update array.

    BatchView::BatchView

    fn[D, T, R] BatchView::BatchView(length : Int, description : Description[T], read~ : (Int) -> (D, T, R)) -> BatchView[D, T, R]

    Adapt immutable external storage as an indexed batch. Rows must be sorted by (data,time), consolidated, and consistent with description. The read callback must return the same row for the lifetime of the view and retain its storage. No eager row copy or scan is performed, so paged and columnar stores can remain lazy. The callback is invoked only for indices in [0,length).

    BatchView::cursor

    fn[K : Compare + Eq, V : Compare + Eq, T, R] BatchView::cursor(self : BatchView[(K, V), T, R]) -> Cursor[K, V, T, R]

    BatchView::description

    fn[D, T, R] BatchView::description(self : BatchView[D, T, R]) -> Description[T]

    BatchView::for_each

    fn[D, T, R] BatchView::for_each(self : BatchView[D, T, R], visit : (D, T, R) -> Unit) -> Unit

    BatchView::for_key

    fn[K : Compare + Eq, V, T, R] BatchView::for_key(self : BatchView[(K, V), T, R], key : K, visit : (V, T, R) -> Unit) -> Unit

    BatchView::frontier

    fn[D, T : Lattice + Compare + Eq, R] BatchView::frontier(self : BatchView[D, T, R], since : Antichain[T], until : Antichain[T]) -> BatchView[D, T, R]

    Advance visible times by since, then suppress times at or beyond until. Like upstream BatchFrontier, length, metadata and cursor keys are unchanged.

    BatchView::get

    fn[D, T, R] BatchView::get(self : BatchView[D, T, R], index : Int) -> (D, T, R)?

    BatchView::is_empty

    fn[D, T, R] BatchView::is_empty(self : BatchView[D, T, R]) -> Bool

    BatchView::length

    fn[D, T, R] BatchView::length(self : BatchView[D, T, R]) -> Int

    BatchView::map_times

    fn[D, T, U : Lattice + Compare + Eq, R] BatchView::map_times(self : BatchView[D, T, R], lift : (T) -> U) -> BatchView[D, U, R]

    Map a batch into a refined timestamp domain. The mapping must be monotonic and preserve the interval and compaction laws; product entry is a typical use.

    BatchView::map_times_at

    fn[D, T, U : Lattice + Compare + Eq, R] BatchView::map_times_at(self : BatchView[D, T, R], lift : (T) -> U, assign : (D, T) -> U) -> BatchView[D, U, R]

    Map record times using the data, while lifting metadata with the scope's refinement. The assignment must preserve the refinement's progress laws.

    BatchView::to_array

    fn[D, T, R] BatchView::to_array(self : BatchView[D, T, R]) -> Array[(D, T, R)]

    Batcher

    pub struct Batcher[D, T, R] {
    // private fields
    }

    Collect updates in geometrically sized sorted chains, then seal intervals at arbitrary antichain frontiers. The explicit minimum adapts Rust Timestamp.

    Batcher::Batcher

    fn[D, T : Lattice + Compare + Eq, R] Batcher::Batcher(minimum : T, logger? : TraceLogger) -> Batcher[D, T, R]

    Batcher::dispose

    fn[D, T : Lattice + Compare + Eq, R] Batcher::dispose(self : Batcher[D, T, R]) -> Unit

    Abandon pending records and release storage without sealing an output batch.

    Batcher::frontier

    fn[D, T : Lattice + Compare + Eq, R] Batcher::frontier(self : Batcher[D, T, R]) -> Antichain[T]

    Frontier of records retained by the most recent seal, after consolidation. New pushes do not update this cached frontier, matching upstream Batcher.

    Batcher::push

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Batcher::push(self : Batcher[D, T, R], chunk : Array[(D, T, R)]) -> Unit

    Consume a chunk; sorting and consolidation are performed before merging it.

    Batcher::seal

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Batcher::seal(self : Batcher[D, T, R], upper : Antichain[T]) -> (Array[Array[(D, T, R)]], Description[T])

    BatcherEvent

    pub(all) struct BatcherEvent {
    operator : Int
    records_diff : Int
    size_diff : Int64?
    capacity_diff : Int64?
    allocations_diff : Int64?
    } derive(Eq,
    Debug
    )

    Record deltas are exact. Byte/capacity/allocation deltas are optional because managed backends do not expose allocator accounting. None means unavailable, never zero bytes. Custom storage can emit measurements in these fields.

    BatcherEvent::equal

    BatcherEvent::not_equal

    fn BatcherEvent::not_equal(x : BatcherEvent, y : BatcherEvent) -> Bool

    BytesSource

    pub struct BytesSource {
    // private fields
    }

    A persistent immutable byte handle. A failed load must abort, as in upstream.

    BytesSource::BytesSource

    fn BytesSource::BytesSource(load : () -> Bytes) -> BytesSource

    BytesSource::load

    fn BytesSource::load(self : BytesSource) -> Bytes

    BytesStore

    pub struct BytesStore {
    // private fields
    }

    Store bytes and return a handle that can reproduce them after this call.

    BytesStore::BytesStore

    fn BytesStore::BytesStore(store : (Bytes) -> BytesSource) -> BytesStore

    BytesStore::store

    fn BytesStore::store(self : BytesStore, bytes : Bytes) -> BytesSource

    Capability

    pub struct Capability[T, S] {
    // private fields
    }

    A counted right to produce at a port. Explicit release replaces Rust Drop.

    Capability::clone

    fn[T : Lattice + Compare + Eq, S] Capability::clone(self : Capability[T, S]) -> Capability[T, S]

    Capability::delayed

    fn[T : Lattice + Compare + Eq, S] Capability::delayed(self : Capability[T, S], time : T) -> Capability[T, S]

    Capability::downgrade

    fn[T : Lattice + Compare + Eq, S] Capability::downgrade(self : Capability[T, S], time : T) -> Unit

    Capability::is_live

    fn[T, S] Capability::is_live(self : Capability[T, S]) -> Bool

    Capability::release

    fn[T : Lattice + Compare + Eq, S] Capability::release(self : Capability[T, S]) -> Unit

    Capability::time

    fn[T, S] Capability::time(self : Capability[T, S]) -> T

    Capability::try_delayed

    fn[T : Lattice + Compare + Eq, S] Capability::try_delayed(self : Capability[T, S], time : T) -> Capability[T, S]?

    Capability::try_downgrade

    fn[T : Lattice + Compare + Eq, S] Capability::try_downgrade(self : Capability[T, S], time : T) -> Bool

    Capability::valid_for

    fn[T, S] Capability::valid_for(self : Capability[T, S], tracker : ProgressTracker[T, S], port : Int) -> Bool

    CapabilitySet

    pub struct CapabilitySet[T, S] {
    // private fields
    }

    Minimal capabilities for one output port. Insertion transfers the input handle.

    CapabilitySet::CapabilitySet

    fn[T : Lattice + Compare + Eq, S] CapabilitySet::CapabilitySet(capability : Capability[T, S]) -> CapabilitySet[T, S]

    CapabilitySet::insert

    fn[T : Lattice + Compare + Eq, S] CapabilitySet::insert(self : CapabilitySet[T, S], capability : Capability[T, S]) -> Unit

    CapabilitySet::release

    fn[T : Lattice + Compare + Eq, S] CapabilitySet::release(self : CapabilitySet[T, S]) -> Unit

    CapabilitySet::times

    fn[T : Lattice + Compare + Eq, S] CapabilitySet::times(self : CapabilitySet[T, S]) -> Array[T]

    CapabilitySet::try_delayed

    fn[T : Lattice + Compare + Eq, S] CapabilitySet::try_delayed(self : CapabilitySet[T, S], time : T) -> Capability[T, S]?

    CapabilitySet::try_downgrade

    fn[T : Lattice + Compare + Eq, S] CapabilitySet::try_downgrade(self : CapabilitySet[T, S], times : Array[T]) -> Bool

    All requested times must be reachable. Validation happens before any release.

    CaptureHandle

    pub struct CaptureHandle {
    // private fields
    }

    Wake or cancel an externally driven capture/replay operator. Cancellation discards uncommitted work; is_complete means normal protocol completion.

    CaptureHandle::activate

    fn CaptureHandle::activate(self : CaptureHandle) -> Unit

    CaptureHandle::cancel

    fn CaptureHandle::cancel(self : CaptureHandle) -> Unit

    CaptureHandle::is_cancelled

    fn CaptureHandle::is_cancelled(self : CaptureHandle) -> Bool

    CaptureHandle::is_complete

    fn CaptureHandle::is_complete(self : CaptureHandle) -> Bool

    CaptureMessage

    pub(all) enum CaptureMessage[D, T, R] {
    Updates(Array[(D, T, R)])
    Progress(CaptureProgress[T])
    }

    CaptureMessage::codec

    fn[D, T : Lattice + Compare + Eq, R] CaptureMessage::codec(data : WireCodec[D], time : WireCodec[T], diff : WireCodec[R]) -> WireCodec[CaptureMessage[D, T, R]]

    A versioned JSON envelope for capture protocol messages. Explicit component codecs preserve custom timestamps and exact integer widths. This is the MoonBit capture format, not Rust serde's binary representation.

    CaptureProgress

    pub struct CaptureProgress[T] {
    // private fields
    }

    Exact distinct update counts in a sealed interval of the capture protocol.

    CaptureProgress::CaptureProgress

    fn[T : Lattice + Compare + Eq] CaptureProgress::CaptureProgress(lower : Antichain[T], upper : Antichain[T], counts : Array[(T, Int64)]) -> CaptureProgress[T]

    CaptureProgress::counts

    fn[T] CaptureProgress::counts(self : CaptureProgress[T]) -> Array[(T, Int64)]

    CaptureProgress::lower

    fn[T : Lattice + Compare + Eq] CaptureProgress::lower(self : CaptureProgress[T]) -> Antichain[T]

    CaptureProgress::upper

    fn[T : Lattice + Compare + Eq] CaptureProgress::upper(self : CaptureProgress[T]) -> Antichain[T]

    CaptureWriter

    pub struct CaptureWriter[D, T, R] {
    // private fields
    }

    Nonblocking capture writer. poll returns a retry delay, or None when the message is accepted. done reports that all accepted writes are committed.

    CaptureWriter::CaptureWriter

    fn[D, T, R] CaptureWriter::CaptureWriter(poll~ : (CaptureMessage[D, T, R]) -> Duration?, done~ : () -> Bool) -> CaptureWriter[D, T, R]

    ChangeBatch

    pub struct ChangeBatch[T] {
    // private fields
    }

    Consolidates signed counts by key, removing zero totals.

    ChangeBatch::ChangeBatch

    fn[T] ChangeBatch::ChangeBatch() -> ChangeBatch[T]

    ChangeBatch::clear

    fn[T] ChangeBatch::clear(self : ChangeBatch[T]) -> Unit

    ChangeBatch::drain

    fn[T : Compare + Eq] ChangeBatch::drain(self : ChangeBatch[T]) -> Array[(T, Int64)]

    ChangeBatch::is_dirty

    fn[T] ChangeBatch::is_dirty(self : ChangeBatch[T]) -> Bool

    ChangeBatch::is_empty

    fn[T : Compare + Eq] ChangeBatch::is_empty(self : ChangeBatch[T]) -> Bool

    ChangeBatch::to_array

    fn[T : Compare + Eq] ChangeBatch::to_array(self : ChangeBatch[T]) -> Array[(T, Int64)]

    ChangeBatch::update

    fn[T : Compare + Eq] ChangeBatch::update(self : ChangeBatch[T], key : T, delta : Int64) -> Unit

    ChangeBatch::update_all

    fn[T : Compare + Eq] ChangeBatch::update_all(self : ChangeBatch[T], changes : Array[(T, Int64)]) -> Unit

    ClusterPoll

    pub(all) enum ClusterPoll {
    Pending
    Progress
    Quiescent
    } derive(Eq,
    Debug
    )

    Pending yields to the host; Progress completed a collective round with work; Quiescent completed a round with no globally scheduled or in-flight work.

    ClusterPoll::equal

    fn ClusterPoll::equal(ClusterPoll, ClusterPoll) -> Bool

    ClusterPoll::not_equal

    fn ClusterPoll::not_equal(x : ClusterPoll, y : ClusterPoll) -> Bool

    ClusterWorker

    pub struct ClusterWorker {
    // private fields
    }

    A worker in a collectively coordinated distributed cluster. The exchange is an ordered all-gather: every peer calls it once per round and receives one payload per peer, in peer-index order. Processes may run operators concurrently between barriers. Supply exchange for blocking I/O or async_exchange for host-polled I/O. Transport errors terminate this worker; replay is never implicit.

    ClusterWorker::ClusterWorker

    fn ClusterWorker::ClusterWorker(index : Int, peers : Int, exchange? : (String) -> Array[String] raise, async_exchange? : AsyncExchange) -> ClusterWorker

    ClusterWorker::dispose

    fn ClusterWorker::dispose(self : ClusterWorker) -> Unit

    Release local state. The caller owns and closes the transport separately.

    ClusterWorker::drop_dataflow

    fn ClusterWorker::drop_dataflow(self : ClusterWorker, id : Int) -> Unit

    Request collective cancellation. Any peer may request it; the next run round cancels that root and all nested scopes on every peer before delivering that round's records. All peers must continue entering run until it is quiescent. Local inputs remain usable until the collective decision is applied.

    ClusterWorker::index

    fn ClusterWorker::index(self : ClusterWorker) -> Int

    ClusterWorker::installed_dataflows

    fn ClusterWorker::installed_dataflows(self : ClusterWorker) -> Array[Int]

    ClusterWorker::next_dataflow_index

    fn ClusterWorker::next_dataflow_index(self : ClusterWorker) -> Int

    ClusterWorker::peers

    fn ClusterWorker::peers(self : ClusterWorker) -> Int

    ClusterWorker::poll

    fn ClusterWorker::poll(self : ClusterWorker) -> ClusterPoll raise

    Advance one collective round, yielding while asynchronous I/O is pending. Operators run when a complete round can publish globally counted progress. Build graphs and submit input epochs before driving every peer to Quiescent. Pending does not mean the input or its output frontier is complete.

    ClusterWorker::run

    fn ClusterWorker::run(self : ClusterWorker, max_rounds? : Int) -> RunResult raise

    All peers must call with the same bound. Quiescent means no scheduled or in-flight work anywhere; open input capabilities may still hold frontiers. An asynchronous exchange returns StepLimit as soon as I/O is pending, even before the round budget is exhausted. Resume run/poll when the host is ready.

    ClusterWorker::scope

    fn[T : Lattice + Compare + Eq, S : Compare + Eq] ClusterWorker::scope(self : ClusterWorker, minimum : T, domain : SummaryDomain[T, S], time_codec~ : WireCodec[T], summary_codec~ : WireCodec[S]) -> DistributedScope[T, S]

    Collection

    pub struct Collection[D, T, R] {
    // private fields
    }

    A stream of timestamped weighted updates within a worker.

    Collection::antijoin

    fn[K : Compare + Hash + Eq, V : Compare + Eq, T : Lattice + Compare + Eq] Collection::antijoin(self : Collection[(K, V), T, Int64], keys : Collection[K, T, Int64]) -> Collection[(K, V), T, Int64]

    Weighted antijoin. For set exclusion the key collection must have weights 0 or 1.

    Collection::arrange_by_key

    fn[K : Compare + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Collection::arrange_by_key(self : Collection[(K, V), T, R], fueled? : Bool, columnar? : Bool, spill? : SpillPolicy[(K, V), T, R]) -> Arranged[K, V, T, R]

    Collection::arrange_by_self

    fn[K : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Collection::arrange_by_self(self : Collection[K, T, R], fueled? : Bool, columnar? : Bool, spill? : SpillPolicy[(K, Unit), T, R]) -> Arranged[K, Unit, T, R]

    Collection::arrange_from_upsert

    fn[K : Compare + Hash + Eq, V : Compare + Eq, T : TotalOrder + Lattice + Compare + Eq] Collection::arrange_from_upsert(self : Collection[(K, V?), T, Present]) -> Arranged[K, V, T, Int64]

    Convert timestamped upserts to a differential arrangement. At equal key/time, Some wins over None, and the greatest present value wins, matching upstream. Upserts require a total timestamp order; repeated values produce no changes.

    Collection::arrange_with

    fn[K : Compare + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Collection::arrange_with(self : Collection[(K, V), T, R], factory : (Antichain[T]) -> TraceBackend[(K, V), T, R]) -> ArrangementView[K, V, T, R]

    Build an arrangement using custom storage. The factory receives the initial frontier and transfers ownership of its returned reader to the arrangement. The optional backend builder receives sorted, consolidated rows; its result must preserve the supplied interval and rows. Shared joins, reductions, nesting and imports operate through the same reader interface.

    Collection::assert_empty

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Collection::assert_empty(self : Collection[D, T, R]) -> Probe[T]

    Assert that all fully consolidated updates are zero. Returns a completion probe so tests can wait until the assertion has checked the entire stream.

    Collection::assert_eq

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Abelian + Monoid + Semigroup] Collection::assert_eq(self : Collection[D, T, R], other : Collection[D, T, R]) -> Probe[T]

    Assert equality of timestamped weighted collections after consolidation.

    Collection::capture

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Collection::capture(self : Collection[D, T, R], emit : (CaptureMessage[D, T, R]) -> Unit) -> Probe[T]

    Capture consolidated updates and their exact counts. The callback owns each update array. Store both update and progress messages to permit replay.

    Collection::concat

    fn[D, T : Lattice + Compare + Eq, R] Collection::concat(self : Collection[D, T, R], other : Collection[D, T, R]) -> Collection[D, T, R]

    Collection::concatenate

    fn[D, T : Lattice + Compare + Eq, R] Collection::concatenate(self : Collection[D, T, R], sources : Array[Collection[D, T, R]]) -> Collection[D, T, R]

    Concatenate this collection and any additional collections in the same scope.

    Collection::consolidate

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Collection::consolidate(self : Collection[D, T, R]) -> Collection[D, T, R]

    Collection::consolidate_stream

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Collection::consolidate_stream(self : Collection[D, T, R]) -> Collection[D, T, R]

    Consolidate each message independently without waiting for progress. Unlike consolidate, cancellations arriving in different messages may remain separate.

    Collection::count

    fn[D : Compare + Hash + Eq, T : Lattice + Compare + Eq, R : Semigroup + Compare + Eq] Collection::count(self : Collection[D, T, R]) -> Collection[(D, R), T, Int64]

    Collection::delay

    fn[D, T : Lattice + Compare + Eq, R] Collection::delay(self : Collection[D, T, R], advance : (T) -> T) -> Collection[D, T, R]

    Delay message capabilities and record timestamps with a pure, monotone, nondecreasing function. Messages are held until the input frontier passes their delayed capability, matching Timely's notification-based delay_batch.

    Collection::distinct

    fn[D : Compare + Hash + Eq, T : Lattice + Compare + Eq, R : Semigroup] Collection::distinct(self : Collection[D, T, R]) -> Collection[D, T, Int64]

    Presence at any nonzero accumulated weight, including a negative weight.

    Collection::enter_dynamic

    fn[D, A, B, R] Collection::enter_dynamic(self : Collection[D, Product[A, PointStamp[B]], R], level : Int) -> Collection[D, Product[A, PointStamp[B]], R]

    Dynamic entry requires no physical coordinate: absent coordinates are minimum.

    Collection::explode

    fn[D, E, T : Lattice + Compare + Eq, R, S] Collection::explode(self : Collection[D, T, R], logic : (D) -> Array[(E, (R) -> S)]) -> Collection[E, T, S]

    General weight transformation, including cross-type multiplication.

    Collection::filter

    fn[D, T : Lattice + Compare + Eq, R] Collection::filter(self : Collection[D, T, R], predicate : (D) -> Bool) -> Collection[D, T, R]

    Collection::flat_map

    fn[D, E, T : Lattice + Compare + Eq, R] Collection::flat_map(self : Collection[D, T, R], logic : (D) -> Array[E]) -> Collection[E, T, R]

    Collection::inspect

    fn[D, T : Lattice + Compare + Eq, R] Collection::inspect(self : Collection[D, T, R], logic : (D, T, R) -> Unit) -> Probe[T]

    Collection::inspect_batch

    fn[D, T : Lattice + Compare + Eq, R] Collection::inspect_batch(self : Collection[D, T, R], logic : (T, Array[(D, T, R)]) -> Unit) -> Collection[D, T, R]

    Observe each batch at its message capability time. Individual updates can have later logical times. Container boundaries may vary between execution backends.

    Collection::inspect_container

    fn[D, T : Lattice + Compare + Eq, R] Collection::inspect_container(self : Collection[D, T, R], logic : (CollectionEvent[D, T, R]) -> Unit) -> Collection[D, T, R]

    Observe copied message containers and progress while forwarding the stream.

    Collection::join

    fn[K : Compare + Hash + Eq, V : Compare + Eq, W : Compare + Eq, T : Lattice + Compare + Eq] Collection::join(self : Collection[(K, V), T, Int64], other : Collection[(K, W), T, Int64]) -> Collection[(K, (V, W)), T, Int64]

    Collection::join_function

    fn[D, E, T : Lattice + Compare + Eq, R, S, O] Collection::join_function(self : Collection[D, T, R], logic : (D) -> Array[(E, T, S)], multiply~ : (S, R) -> O) -> Collection[E, T, O]

    Join each input update with a computed set of weighted, timestamped rows. Timestamps join in the lattice; multiplication receives computed weight first, then the input weight, as in upstream join_function.

    Collection::join_map

    fn[K : Compare + Hash + Eq, V : Compare + Eq, W : Compare + Eq, D, T : Lattice + Compare + Eq, R : Semigroup, S : Semigroup, O] Collection::join_map(self : Collection[(K, V), T, R], other : Collection[(K, W), T, S], logic : (K, V, W) -> D, multiply~ : (R, S) -> O) -> Collection[D, T, O]

    Incremental weighted equijoin; timestamps combine with lattice join. Multiplication may map two different weight types to a third type.

    Collection::map

    fn[D, E, T : Lattice + Compare + Eq, R] Collection::map(self : Collection[D, T, R], logic : (D) -> E) -> Collection[E, T, R]

    Collection::map_in_place

    fn[D, T : Lattice + Compare + Eq, R] Collection::map_in_place(self : Collection[D, T, R], logic : (
    Ref
    [D]) -> Unit) -> Collection[D, T, R]

    Mutable record transformation. The reference holds the current record and its replacement; logical time and difference are unchanged.

    Collection::negate

    fn[D, T : Lattice + Compare + Eq, R : Abelian + Monoid + Semigroup] Collection::negate(self : Collection[D, T, R]) -> Collection[D, T, R]

    Collection::probe

    fn[D, T : Lattice + Compare + Eq, R] Collection::probe(self : Collection[D, T, R]) -> Probe[T]

    Collection::probe_with

    fn[D, T : Lattice + Compare + Eq, R] Collection::probe_with(self : Collection[D, T, R], probe : Probe[T]) -> Collection[D, T, R]

    Observe progress jointly across multiple collections. The handle's frontier is the union of their frontiers; it completes only after every attached stream.

    Collection::reduce

    fn[K : Compare + Hash + Eq, V : Compare + Eq, W : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup, S : Abelian + Monoid + Semigroup] Collection::reduce(self : Collection[(K, V), T, R], logic : (K, Array[(V, R)]) -> Array[(W, S)]) -> Collection[(K, W), T, S]

    Pure grouped reduction with partial-order timestamp semantics. Uses the join-closure algorithm, compacting history at arbitrary antichain frontiers.

    Collection::reduce_core

    fn[K : Compare + Hash + Eq, V : Compare + Eq, W : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup, S : Semigroup] Collection::reduce_core(self : Collection[(K, V), T, R], logic : (K, Array[(V, R)], Array[(W, S)]) -> Array[(W, S)]) -> Arranged[K, W, T, S]

    Compute corrections using input and existing output snapshots. The returned arrangement owns a shared index; release it when no longer needed.

    Collection::results_in

    fn[D, T : Lattice + Compare + Eq, R, S] Collection::results_in(self : Collection[D, T, R], step : S, domain : SummaryDomain[T, S]) -> Collection[D, T, R]

    Advance logical record times by a summary, retaining the message capability. Overflowed record timestamps are discarded. As upstream, results must still lie at or beyond the enclosing message capability.

    Collection::semijoin

    fn[K : Compare + Hash + Eq, V : Compare + Eq, T : Lattice + Compare + Eq] Collection::semijoin(self : Collection[(K, V), T, Int64], keys : Collection[K, T, Int64]) -> Collection[(K, V), T, Int64]

    Collection::threshold

    fn[D : Compare + Hash + Eq, T : Lattice + Compare + Eq, R : Semigroup, S : Abelian + Monoid + Semigroup] Collection::threshold(self : Collection[D, T, R], logic : (D, R) -> S) -> Collection[D, T, S]

    CollectionEvent

    pub(all) enum CollectionEvent[D, T, R] {
    Records(T, Array[(D, T, R)])
    Frontier(Antichain[T])
    }

    Data messages retain their capability timestamp separately from the logical timestamp in each update. Frontiers describe future message capabilities.

    ColumnCodec

    pub struct ColumnCodec[A] {
    // private fields
    }

    Schema for a Rust columnar value container. Slices are the component columns in upstream AsBytes order; all integers use little-endian encoding. Custom structs/enums can supply their own schema without changing trie framing.

    ColumnCodec::ColumnCodec

    fn[A] ColumnCodec::ColumnCodec(slices~ : Int, encode~ : (Array[A]) -> Array[Bytes], decode~ : (Array[BytesView], Int) -> Array[A]?) -> ColumnCodec[A]

    ColumnCodec::bool

    fn ColumnCodec::bool() -> ColumnCodec[Bool]

    ColumnCodec::byte

    fn ColumnCodec::byte() -> ColumnCodec[Byte]

    ColumnCodec::bytes

    fn ColumnCodec::bytes() -> ColumnCodec[Bytes]

    ColumnCodec::double

    fn ColumnCodec::double() -> ColumnCodec[Double]

    ColumnCodec::duration

    fn ColumnCodec::duration() -> ColumnCodec[Duration]

    ColumnCodec::int16

    fn ColumnCodec::int16() -> ColumnCodec[Int16]

    ColumnCodec::int32

    fn ColumnCodec::int32() -> ColumnCodec[Int]

    ColumnCodec::int64

    fn ColumnCodec::int64() -> ColumnCodec[Int64]

    ColumnCodec::int8

    ColumnCodec::map

    fn[A, B] ColumnCodec::map(self : ColumnCodec[A], encode : (B) -> A, decode : (A) -> B?) -> ColumnCodec[B]

    Adapt a storage schema through checked owned-value conversions.

    ColumnCodec::pair

    fn[A, B] ColumnCodec::pair(left : ColumnCodec[A], right : ColumnCodec[B]) -> ColumnCodec[(A, B)]

    ColumnCodec::product

    fn[A, B] ColumnCodec::product(outer : ColumnCodec[A], inner : ColumnCodec[B]) -> ColumnCodec[Product[A, B]]

    ColumnCodec::string

    fn ColumnCodec::string() -> ColumnCodec[String]

    ColumnCodec::uint16

    fn ColumnCodec::uint16() -> ColumnCodec[UInt16]

    ColumnCodec::uint32

    fn ColumnCodec::uint32() -> ColumnCodec[UInt]

    ColumnCodec::uint64

    fn ColumnCodec::uint64() -> ColumnCodec[UInt64]

    ColumnCodec::unit

    fn ColumnCodec::unit() -> ColumnCodec[Unit]

    ColumnCodec::vector

    fn[A] ColumnCodec::vector(item : ColumnCodec[A]) -> ColumnCodec[Array[A]]

    Rust Vec containers use a plain u64 end-offset column followed by the item schema (unlike trie lists, whose offsets use the Strides representation).

    ColumnLists

    pub struct ColumnLists[A] {
    // private fields
    }

    Immutable lists sharing one value column, delimited by cumulative end offsets. Constructors copy their arrays; views can be retained across builder updates.

    ColumnLists::ColumnLists

    fn[A] ColumnLists::ColumnLists(values : Array[A], ends : Array[Int]) -> ColumnLists[A]

    ColumnLists::bounds

    fn[A] ColumnLists::bounds(self : ColumnLists[A], index : Int) -> (Int, Int)

    ColumnLists::get

    fn[A] ColumnLists::get(self : ColumnLists[A], index : Int) -> A

    ColumnLists::length

    fn[A] ColumnLists::length(self : ColumnLists[A]) -> Int

    ColumnLists::offsets

    fn[A] ColumnLists::offsets(self : ColumnLists[A]) -> Array[Int]

    ColumnLists::retain_items

    fn[A] ColumnLists::retain_items(self : ColumnLists[A], keep : Array[Bool]) -> (ColumnLists[A], Array[Bool])

    Keep selected values, remove empty lists, and return a bitmap of surviving lists.

    ColumnLists::value_count

    fn[A] ColumnLists::value_count(self : ColumnLists[A]) -> Int

    ColumnLists::values

    fn[A] ColumnLists::values(self : ColumnLists[A]) -> Array[A]

    ColumnarBatch

    pub struct ColumnarBatch[K, V, T, R] {
    // private fields
    }

    Immutable key/value/time/difference columns. Repeated keys and values are represented once, with offsets delimiting their sorted child ranges.

    ColumnarBatch::ColumnarBatch

    fn[K : Compare + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] ColumnarBatch::ColumnarBatch(updates : Array[((K, V), T, R)], lower~ : Antichain[T], upper~ : Antichain[T]) -> ColumnarBatch[K, V, T, R]

    ColumnarBatch::batch

    fn[K : Eq, V : Eq, T, R] ColumnarBatch::batch(self : ColumnarBatch[K, V, T, R]) -> Batch[(K, V), T, R]

    Share these columns with ordinary trace, spine, merge and cursor APIs.

    ColumnarBatch::storage_counts

    fn[K, V, T, R] ColumnarBatch::storage_counts(self : ColumnarBatch[K, V, T, R]) -> (Int, Int, Int)

    Number of stored keys, values and time/difference pairs (excluding offsets).

    ColumnarBatch::updates

    fn[K, V, T, R] ColumnarBatch::updates(self : ColumnarBatch[K, V, T, R]) -> UpdatesTyped[K, V, T, R]

    Expose an existing columnar batch as a consolidated trie without copying its values. Offset arrays are adapted to the trie list convention.

    ColumnarCodec

    pub struct ColumnarCodec[K, V, T, R] {
    // private fields
    }

    Pinned Rust Updates framing: four little-endian u64 column lengths followed by four indexed Stash encodings. Schemas must match the Rust value types.

    ColumnarCodec::ColumnarCodec

    fn[K, V, T, R] ColumnarCodec::ColumnarCodec(key : ColumnCodec[K], val : ColumnCodec[V], time : ColumnCodec[T], diff : ColumnCodec[R]) -> ColumnarCodec[K, V, T, R]

    ColumnarCodec::decode

    fn[K, V, T, R] ColumnarCodec::decode(self : ColumnarCodec[K, V, T, R], bytes : BytesView, max_values? : Int) -> UpdatesTyped[K, V, T, R]?

    Decode owned columns, checking framing, offsets and parent/child counts. max_values bounds each column's element/list counts, including zero-sized elements. Decoded raw tries can be consolidated before chunk operations.

    ColumnarCodec::encode

    fn[K, V, T, R] ColumnarCodec::encode(self : ColumnarCodec[K, V, T, R], updates : UpdatesTyped[K, V, T, R]) -> Bytes

    ColumnarCodec::spill_policy

    fn[K : Compare + Eq, V : Compare + Eq, T : Compare + Eq, R : Semigroup] ColumnarCodec::spill_policy(self : ColumnarCodec[K, V, T, R], budget_records : Int64, store~ : BytesStore, chunk_size? : Int) -> SpillPolicy[(K, V), T, R]

    Page trace batches using the exact Rust columnar Updates encoding. The policy keeps the same high-water budget and one-page-per-reader cache.

    Cursor

    pub struct Cursor[K, V, T, R] {
    // private fields
    }

    A cursor merging retained immutable batch indexes. Construction retains the batches without copying update history. Times are visited per batch and are not consolidated across batches, matching upstream CursorList.

    Cursor::Cursor

    fn[K : Compare + Eq, V : Compare + Eq, T, R] Cursor::Cursor(batches : Array[BatchView[(K, V), T, R]]) -> Cursor[K, V, T, R]

    Cursor::key

    fn[K, V, T, R] Cursor::key(self : Cursor[K, V, T, R]) -> K?

    Cursor::key_valid

    fn[K, V, T, R] Cursor::key_valid(self : Cursor[K, V, T, R]) -> Bool

    Cursor::map_times

    fn[K, V, T, R] Cursor::map_times(self : Cursor[K, V, T, R], visit : (T, R) -> Unit) -> Unit

    Cursor::rewind_keys

    fn[K : Compare + Eq, V : Compare + Eq, T, R] Cursor::rewind_keys(self : Cursor[K, V, T, R]) -> Unit

    Cursor::rewind_vals

    fn[K, V : Compare + Eq, T, R] Cursor::rewind_vals(self : Cursor[K, V, T, R]) -> Unit

    Cursor::seek_key

    fn[K : Compare + Eq, V : Compare + Eq, T, R] Cursor::seek_key(self : Cursor[K, V, T, R], key : K) -> Unit

    Cursor::seek_val

    fn[K, V : Compare + Eq, T, R] Cursor::seek_val(self : Cursor[K, V, T, R], value : V) -> Unit

    Cursor::step_key

    fn[K : Compare + Eq, V : Compare + Eq, T, R] Cursor::step_key(self : Cursor[K, V, T, R]) -> Unit

    Cursor::step_val

    fn[K, V : Compare + Eq, T, R] Cursor::step_val(self : Cursor[K, V, T, R]) -> Unit

    Cursor::times

    fn[K, V, T, R] Cursor::times(self : Cursor[K, V, T, R]) -> Array[(T, R)]

    Cursor::val

    fn[K, V, T, R] Cursor::val(self : Cursor[K, V, T, R]) -> V?

    Cursor::val_valid

    fn[K, V, T, R] Cursor::val_valid(self : Cursor[K, V, T, R]) -> Bool

    Description

    pub struct Description[T] {
    // private fields
    }

    A timestamp interval [lower, upper), observed at compaction frontier since.

    Description::Description

    fn[T : Lattice + Compare + Eq] Description::Description(lower : Antichain[T], upper : Antichain[T], since : Antichain[T]) -> Description[T]

    Description::lower

    fn[T : Lattice + Compare + Eq] Description::lower(self : Description[T]) -> Antichain[T]

    Description::since

    fn[T : Lattice + Compare + Eq] Description::since(self : Description[T]) -> Antichain[T]

    Description::upper

    fn[T : Lattice + Compare + Eq] Description::upper(self : Description[T]) -> Antichain[T]

    DifferentialEvent

    pub(all) enum DifferentialEvent {
    BatchCreated(BatchEvent)
    MergeProgress(MergeEvent)
    BatchDropped(DropEvent)
    MergeShortfall(MergeShortfall)
    TraceShare(TraceShare)
    BatcherSize(BatcherEvent)
    } derive(Eq,
    Debug
    )

    DifferentialEvent::equal

    DifferentialEvent::not_equal

    fn DifferentialEvent::not_equal(x : DifferentialEvent, y : DifferentialEvent) -> Bool

    DistributedNestedScope

    pub struct DistributedNestedScope[A, B, S, U] {
    // private fields
    }

    A nested timestamp domain coordinated by the same distributed cluster.

    DistributedNestedScope::enter

    fn[D, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R, S, U] DistributedNestedScope::enter(self : DistributedNestedScope[A, B, S, U], source : Collection[D, A, R]) -> Collection[D, Product[A, B], R]

    DistributedNestedScope::leave

    fn[D, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R, S, U] DistributedNestedScope::leave(self : DistributedNestedScope[A, B, S, U], source : Collection[D, Product[A, B], R]) -> Collection[D, A, R]

    DistributedNestedScope::scope

    fn[A, B, S, U] DistributedNestedScope::scope(self : DistributedNestedScope[A, B, S, U]) -> DistributedScope[Product[A, B], Product[S, U]]

    DistributedScope

    pub struct DistributedScope[T, S] {
    // private fields
    }

    Build the same scopes, ports, summaries and exchanges in the same order on every peer. Data, input capabilities and input progress may differ by peer.

    DistributedScope::dataflow_index

    fn[T, S] DistributedScope::dataflow_index(self : DistributedScope[T, S]) -> Int

    DistributedScope::exchange

    fn[D, T : Lattice + Compare + Eq, R, S] DistributedScope::exchange(self : DistributedScope[T, S], source : Collection[D, T, R], hash : (D) -> UInt64, data_codec~ : WireCodec[D], time_codec~ : WireCodec[T], diff_codec~ : WireCodec[R]) -> Collection[D, T, R]

    Keyed exchange. Outgoing records first acquire transit pointstamps. On receipt those pointstamps are replaced by downstream mailbox counts in the next round. Consequently neither network latency nor uneven execution can advance a frontier past an undelivered record.

    DistributedScope::input

    fn[D, T : Lattice + Compare + Eq, R, S] DistributedScope::input(self : DistributedScope[T, S]) -> (InputSession[D, T, R], Collection[D, T, R])

    DistributedScope::iterate

    fn[D, T : Lattice + Compare + Eq, R : Abelian + Monoid + Semigroup, S : Compare + Eq] DistributedScope::iterate(self : DistributedScope[T, S], source : Collection[D, T, R], logic : (DistributedScope[Product[T, Int64], Product[S, Int64]], Collection[D, Product[T, Int64], R]) -> Collection[D, Product[T, Int64], R]) -> Collection[D, T, R]

    Exchange within the child scope before applying keyed fixed-point operators.

    DistributedScope::nested

    fn[A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, S : Compare + Eq, U : Compare + Eq] DistributedScope::nested(self : DistributedScope[A, S], minimum : B, domain : SummaryDomain[B, U], time_codec~ : WireCodec[B], summary_codec~ : WireCodec[U]) -> DistributedNestedScope[A, B, S, U]

    DistributedScope::replay_from

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Compare + Eq, S] DistributedScope::replay_from(self : DistributedScope[T, S], build_source : (Activator) -> (() -> CaptureMessage[D, T, R]?), codec~ : WireCodec[CaptureMessage[D, T, R]], hash~ : (D) -> UInt64, time_hash? : (T) -> UInt64, messages_per_turn? : Int) -> (CaptureHandle, Collection[D, T, R])

    Reconstruct a captured collection with partitioned deduplication and timestamp accounting. Only compact progress frontiers are broadcast. Build matching codecs and hashes on every peer. The default count partition hashes the time codec's JSON representation; time_hash can override this for interoperability.

    DistributedScope::scope

    fn[T, S] DistributedScope::scope(self : DistributedScope[T, S]) -> Scope[T, S]

    DropEvent

    pub(all) struct DropEvent {
    operator : Int
    length : Int
    } derive(Eq,
    Debug
    )

    DropEvent::equal

    fn DropEvent::equal(DropEvent, DropEvent) -> Bool

    DropEvent::not_equal

    fn DropEvent::not_equal(x : DropEvent, y : DropEvent) -> Bool

    Duration

    pub struct Duration {
    // private fields
    } derive(Compare, Eq, Hash,
    Debug
    )

    Rust Duration-compatible timestamp: unsigned seconds and subsecond nanoseconds.
    impl Lattice for Duration

    Duration::Duration

    fn Duration::Duration(seconds : UInt64, nanoseconds? : UInt) -> Duration

    Normalize nanoseconds; overflow beyond the largest duration is rejected.

    Duration::checked_add

    fn Duration::checked_add(self : Duration, other : Duration) -> Duration?

    Duration::compare

    fn Duration::compare(Duration, Duration) -> Int

    Duration::equal

    fn Duration::equal(Duration, Duration) -> Bool

    Duration::hash

    fn Duration::hash(self : Duration) -> Int

    Duration::hash_combine

    fn Duration::hash_combine(Duration, Hasher) -> Unit

    Duration::join

    fn Duration::join(self : Duration, other : Duration) -> Duration

    Duration::less_equal

    fn Duration::less_equal(self : Duration, other : Duration) -> Bool

    Duration::meet

    fn Duration::meet(self : Duration, other : Duration) -> Duration

    Duration::minimum

    fn Duration::minimum() -> Duration

    Duration::nanoseconds

    fn Duration::nanoseconds(self : Duration) -> UInt

    Duration::not_equal

    fn Duration::not_equal(x : Duration, y : Duration) -> Bool

    Duration::op_ge

    fn Duration::op_ge(x : Duration, y : Duration) -> Bool

    Duration::op_gt

    fn Duration::op_gt(x : Duration, y : Duration) -> Bool

    Duration::op_le

    fn Duration::op_le(x : Duration, y : Duration) -> Bool

    Duration::op_lt

    fn Duration::op_lt(x : Duration, y : Duration) -> Bool

    Duration::seconds

    fn Duration::seconds(self : Duration) -> UInt64

    Duration::to_repr

    Feedback

    pub struct Feedback[D, T, R, S] {
    // private fields
    }

    A feedback edge shifts timestamps by a path summary. Connect exactly once before execution. Individual summaries may move time backward; cycles must still admit convergent reachability summaries. Summary functions must satisfy the domain laws.

    Feedback::connect

    fn[D, T : Lattice + Compare + Eq, R, S] Feedback::connect(self : Feedback[D, T, R, S], source : Collection[D, T, R]) -> Unit

    Overflowing timestamp advancement drops the record, matching Timely's feedback operator.

    FnvHasher

    pub struct FnvHasher {
    // private fields
    }

    FNV-1a hasher used by upstream Hashable. Numeric writes use little-endian encoding, matching the pinned Rust oracle on supported 64-bit hosts.

    FnvHasher::FnvHasher

    fn FnvHasher::FnvHasher() -> FnvHasher

    FnvHasher::finish

    fn FnvHasher::finish(self : FnvHasher) -> UInt64

    FnvHasher::write

    fn FnvHasher::write(self : FnvHasher, bytes : BytesView) -> Unit

    FnvHasher::write_byte

    fn FnvHasher::write_byte(self : FnvHasher, value : Byte) -> Unit

    FnvHasher::write_word

    fn FnvHasher::write_word(self : FnvHasher, value : UInt64, width : Int) -> Unit

    InputCapability

    pub struct InputCapability[T, S] {
    // private fields
    }

    A borrowed input timestamp. Convert it to an owned output capability through delayed; the declared path summaries determine which times are permitted.

    InputCapability::delayed

    fn[D, T : Lattice + Compare + Eq, R, S] InputCapability::delayed(self : InputCapability[T, S], output : Output[D, T, R, S], time : T) -> Capability[T, S]

    InputCapability::time

    fn[T, S] InputCapability::time(self : InputCapability[T, S]) -> T

    InputCapability::try_delayed

    fn[D, T : Lattice + Compare + Eq, R, S] InputCapability::try_delayed(self : InputCapability[T, S], output : Output[D, T, R, S], time : T) -> Capability[T, S]?

    InputSession

    pub struct InputSession[D, T, R] {
    // private fields
    }

    Buffered timestamped input. The delivery callback receives data before its new frontier. Close explicitly to release the final capability; callbacks must not re-enter the session.

    InputSession::InputSession

    fn[D, T : Lattice + Compare + Eq, R] InputSession::InputSession(initial : T, deliver~ : (Array[(D, T, R)], Antichain[T]) -> Unit, buffer_limit? : Int) -> InputSession[D, T, R]

    InputSession::advance_to

    fn[D, T : Lattice + Compare + Eq, R] InputSession::advance_to(self : InputSession[D, T, R], time : T) -> Unit

    Advance local time. Progress is published only on flush or close.

    InputSession::close

    fn[D, T : Lattice + Compare + Eq, R] InputSession::close(self : InputSession[D, T, R]) -> Unit

    InputSession::flush

    fn[D, T : Lattice + Compare + Eq, R] InputSession::flush(self : InputSession[D, T, R]) -> Unit

    InputSession::frontier

    fn[D, T : Lattice + Compare + Eq, R] InputSession::frontier(self : InputSession[D, T, R]) -> Antichain[T]

    InputSession::insert

    fn[D, T : Lattice + Compare + Eq] InputSession::insert(self : InputSession[D, T, Int64], data : D) -> Unit

    InputSession::remove

    fn[D, T : Lattice + Compare + Eq] InputSession::remove(self : InputSession[D, T, Int64], data : D) -> Unit

    InputSession::time

    fn[D, T, R] InputSession::time(self : InputSession[D, T, R]) -> T

    InputSession::update

    fn[D, T : Lattice + Compare + Eq, R] InputSession::update(self : InputSession[D, T, R], data : D, diff : R) -> Unit

    InputSession::update_at

    fn[D, T : Lattice + Compare + Eq, R] InputSession::update_at(self : InputSession[D, T, R], data : D, time : T, diff : R) -> Unit

    Int128

    pub struct Int128 {
    // private fields
    } derive(Compare, Eq, Hash,
    Debug
    )

    Fixed-width signed 128-bit integer. Difference arithmetic wraps modulo 2^128; timestamp summary arithmetic detects overflow. Storage uses core BigInt.
    impl Abelian for Int128
    impl Lattice for Int128
    impl Monoid for Int128
    impl Ring for Int128
    impl RustHash for Int128
    impl Semigroup for Int128
    impl Timestamp for Int128

    Int128::Int128

    fn Int128::Int128(value : Int64) -> Int128

    Int128::checked_add

    fn Int128::checked_add(self : Int128, other : Int128) -> Int128?

    Int128::compare

    fn Int128::compare(Int128, Int128) -> Int

    Int128::equal

    fn Int128::equal(Int128, Int128) -> Bool

    Int128::from_words

    fn Int128::from_words(high : Int64, low : UInt64) -> Int128

    Int128::hash

    fn Int128::hash(self : Int128) -> Int

    Int128::hash_combine

    fn Int128::hash_combine(Int128, Hasher) -> Unit

    Int128::hash_into

    fn Int128::hash_into(self : Int128, hasher : FnvHasher) -> Unit

    Int128::is_zero

    fn Int128::is_zero(self : Int128) -> Bool

    Int128::join

    fn Int128::join(self : Int128, other : Int128) -> Int128

    Int128::less_equal

    fn Int128::less_equal(self : Int128, other : Int128) -> Bool

    Int128::meet

    fn Int128::meet(self : Int128, other : Int128) -> Int128

    Int128::minimum

    fn Int128::minimum() -> Int128

    Int128::multiply

    fn Int128::multiply(self : Int128, other : Int128) -> Int128

    Int128::negate

    fn Int128::negate(self : Int128) -> Int128

    Int128::not_equal

    fn Int128::not_equal(x : Int128, y : Int128) -> Bool

    Int128::one

    fn Int128::one() -> Int128

    Int128::op_ge

    fn Int128::op_ge(x : Int128, y : Int128) -> Bool

    Int128::op_gt

    fn Int128::op_gt(x : Int128, y : Int128) -> Bool

    Int128::op_le

    fn Int128::op_le(x : Int128, y : Int128) -> Bool

    Int128::op_lt

    fn Int128::op_lt(x : Int128, y : Int128) -> Bool

    Int128::plus

    fn Int128::plus(self : Int128, other : Int128) -> Int128

    Int128::to_repr

    Int128::to_string

    fn Int128::to_string(self : Int128) -> String

    Int128::to_words

    fn Int128::to_words(self : Int128) -> (Int64, UInt64)

    Int128::try_from_bigint

    fn Int128::try_from_bigint(value :
    BigInt
    ) -> Int128?

    Int128::zero

    fn Int128::zero() -> Int128

    Int8

    pub struct Int8 {
    // private fields
    } derive(Compare, Eq, Hash,
    Debug
    )

    Signed 8-bit integer. Construction and difference arithmetic wrap modulo 256; timestamp advancement uses checked addition instead.
    impl Abelian for Int8
    impl Lattice for Int8
    impl Monoid for Int8
    impl Ring for Int8
    impl RustHash for Int8
    impl Semigroup for Int8
    impl Timestamp for Int8
    impl TotalOrder for Int8

    Int8::Int8

    fn Int8::Int8(value : Int) -> Int8

    Int8::checked_add

    fn Int8::checked_add(self : Int8, other : Int8) -> Int8?

    Int8::compare

    fn Int8::compare(Int8, Int8) -> Int

    Int8::equal

    fn Int8::equal(Int8, Int8) -> Bool

    Int8::hash

    fn Int8::hash(self : Int8) -> Int

    Int8::hash_combine

    fn Int8::hash_combine(Int8, Hasher) -> Unit

    Int8::hash_into

    fn Int8::hash_into(self : Int8, hasher : FnvHasher) -> Unit

    Int8::is_zero

    fn Int8::is_zero(self : Int8) -> Bool

    Int8::join

    fn Int8::join(self : Int8, other : Int8) -> Int8

    Int8::less_equal

    fn Int8::less_equal(self : Int8, other : Int8) -> Bool

    Int8::meet

    fn Int8::meet(self : Int8, other : Int8) -> Int8

    Int8::minimum

    fn Int8::minimum() -> Int8

    Int8::multiply

    fn Int8::multiply(self : Int8, other : Int8) -> Int8

    Int8::negate

    fn Int8::negate(self : Int8) -> Int8

    Int8::not_equal

    fn Int8::not_equal(x : Int8, y : Int8) -> Bool

    Int8::one

    fn Int8::one() -> Int8

    Int8::op_ge

    fn Int8::op_ge(x : Int8, y : Int8) -> Bool

    Int8::op_gt

    fn Int8::op_gt(x : Int8, y : Int8) -> Bool

    Int8::op_le

    fn Int8::op_le(x : Int8, y : Int8) -> Bool

    Int8::op_lt

    fn Int8::op_lt(x : Int8, y : Int8) -> Bool

    Int8::plus

    fn Int8::plus(self : Int8, other : Int8) -> Int8

    Int8::to_int

    fn Int8::to_int(self : Int8) -> Int

    Int8::to_repr

    Int8::zero

    fn Int8::zero() -> Int8

    LogRegistry

    pub struct LogRegistry[E] {
    // private fields
    }

    Typed logging registry. Replacement/removal affects future lookups; retained logger handles continue publishing to their original sink.

    LogRegistry::LogRegistry

    fn[E] LogRegistry::LogRegistry() -> LogRegistry[E]

    LogRegistry::flush

    fn[E] LogRegistry::flush(self : LogRegistry[E]) -> Unit

    LogRegistry::get

    fn[E] LogRegistry::get(self : LogRegistry[E], name : String) -> Logger[E]?

    LogRegistry::insert

    fn[E] LogRegistry::insert(self : LogRegistry[E], name : String, logger : Logger[E]) -> Logger[E]?

    LogRegistry::remove

    fn[E] LogRegistry::remove(self : LogRegistry[E], name : String) -> Logger[E]?

    Logger

    pub struct Logger[E] {
    // private fields
    }

    A typed, buffered logger. Publish owns its batch. Call flush at host polling boundaries; reaching capacity also flushes. The supplied clock is monotone.

    Logger::Logger

    fn[E] Logger::Logger(clock~ : () -> Duration, publish~ : (Duration, Array[(Duration, E)]) -> Unit, capacity? : Int) -> Logger[E]

    Logger::flush

    fn[E] Logger::flush(self : Logger[E]) -> Unit

    Publish the current batch once, including an empty batch to advance logging time without new events. Events logged by the callback stay queued for the next flush, so a callback cannot cause recursive publication.

    Logger::log

    fn[E] Logger::log(self : Logger[E], event : E) -> Unit

    Logger::log_many

    fn[E] Logger::log_many(self : Logger[E], events : Array[E]) -> Unit

    Record a group of events with one timestamp before publication.

    Logger::pending

    fn[E] Logger::pending(self : Logger[E]) -> Int

    MergeEvent

    pub(all) struct MergeEvent {
    operator : Int
    scale : Int
    length1 : Int
    length2 : Int
    complete : Int?
    } derive(Eq,
    Debug
    )

    MergeEvent::equal

    fn MergeEvent::equal(MergeEvent, MergeEvent) -> Bool

    MergeEvent::not_equal

    fn MergeEvent::not_equal(x : MergeEvent, y : MergeEvent) -> Bool

    MergeShortfall

    pub(all) struct MergeShortfall {
    operator : Int
    scale : Int
    shortfall : Int
    } derive(Eq,
    Debug
    )

    MergeShortfall::equal

    MergeShortfall::not_equal

    fn MergeShortfall::not_equal(x : MergeShortfall, y : MergeShortfall) -> Bool

    MutableAntichain

    pub struct MutableAntichain[T] {
    // private fields
    }

    Reference counts of outstanding timestamps and their minimal positive frontier.

    MutableAntichain::MutableAntichain

    fn[T : Lattice + Compare + Eq] MutableAntichain::MutableAntichain() -> MutableAntichain[T]

    MutableAntichain::clear

    fn[T] MutableAntichain::clear(self : MutableAntichain[T]) -> Unit

    MutableAntichain::count_for

    fn[T : Lattice + Compare + Eq] MutableAntichain::count_for(self : MutableAntichain[T], time : T) -> Int64

    MutableAntichain::frontier

    fn[T : Lattice + Compare + Eq] MutableAntichain::frontier(self : MutableAntichain[T]) -> Antichain[T]

    MutableAntichain::update_all

    fn[T : Lattice + Compare + Eq] MutableAntichain::update_all(self : MutableAntichain[T], changes : Array[(T, Int64)]) -> Array[(T, Int64)]

    Apply a batch atomically and return only changes to frontier membership.

    MutableAntichain::updates

    fn[T : Lattice + Compare + Eq] MutableAntichain::updates(self : MutableAntichain[T]) -> Array[(T, Int64)]

    NestedScope

    pub struct NestedScope[A, B, S, U] {
    // private fields
    }

    A nested timestamp domain. Enter adds an inner coordinate; leave projects it away while retaining parent progress until all inner work at that time finishes.

    NestedScope::enter

    fn[D, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R, S, U] NestedScope::enter(self : NestedScope[A, B, S, U], source : Collection[D, A, R]) -> Collection[D, Product[A, B], R]

    NestedScope::enter_at

    fn[D, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R, S, U] NestedScope::enter_at(self : NestedScope[A, B, S, U], source : Collection[D, A, R], assign : (D, A) -> B) -> Collection[D, Product[A, B], R]

    NestedScope::leave

    fn[D, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R, S, U] NestedScope::leave(self : NestedScope[A, B, S, U], source : Collection[D, Product[A, B], R]) -> Collection[D, A, R]

    NestedScope::scope

    fn[A, B, S, U] NestedScope::scope(self : NestedScope[A, B, S, U]) -> Scope[Product[A, B], Product[S, U]]

    NestedScopeGroup

    pub struct NestedScopeGroup[A, B, S, U] {
    // private fields
    }

    NestedScopeGroup::enter

    fn[D, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R, S, U] NestedScopeGroup::enter(self : NestedScopeGroup[A, B, S, U], sources : Array[Collection[D, A, R]]) -> Array[Collection[D, Product[A, B], R]]

    NestedScopeGroup::leave

    fn[D, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R, S, U] NestedScopeGroup::leave(self : NestedScopeGroup[A, B, S, U], sources : Array[Collection[D, Product[A, B], R]]) -> Array[Collection[D, A, R]]

    NestedScopeGroup::scope

    fn[A, B, S, U] NestedScopeGroup::scope(self : NestedScopeGroup[A, B, S, U]) -> ScopeGroup[Product[A, B], Product[S, U]]

    Notificator

    pub struct Notificator[T, S] {
    // private fields
    }

    Timestamp notifications retain output capabilities until all input frontiers pass. Handles returned by drain_ready belong to the caller and must be released.

    Notificator::Notificator

    fn[T, S] Notificator::Notificator() -> Notificator[T, S]

    Notificator::drain_ready

    fn[T : Lattice + Compare + Eq, S] Notificator::drain_ready(self : Notificator[T, S], frontiers : Array[Antichain[T]]) -> Array[(Capability[T, S], Int64)]

    Notificator::release

    fn[T : Lattice + Compare + Eq, S] Notificator::release(self : Notificator[T, S]) -> Unit

    Notificator::request

    fn[T : Lattice + Compare + Eq, S] Notificator::request(self : Notificator[T, S], capability : Capability[T, S]) -> Unit

    Transfer this capability into the notification queue. Equal timestamps at the same output port coalesce, with their request count returned by drain_ready.

    OperatorBuilder

    pub struct OperatorBuilder[T, S] {
    // private fields
    }

    Construct a custom operator with heterogeneous inputs and outputs. New pairs have identity connectivity; set_connection replaces it before build. Build and connect the entire graph before executing the worker.

    OperatorBuilder::activator

    fn[T, S] OperatorBuilder::activator(self : OperatorBuilder[T, S]) -> Activator

    OperatorBuilder::build

    fn[T : Compare + Eq, S] OperatorBuilder::build(self : OperatorBuilder[T, S], construct : (Array[Capability[T, S]]) -> (() -> Unit), on_shutdown? : () -> Unit) -> Unit

    Initial capabilities are owned by the builder callback, in output creation order. Release them when no longer needed. The returned function runs when any input has data or a frontier change; it may drain heterogeneous inputs.

    OperatorBuilder::build_reschedule

    fn[T : Compare + Eq, S] OperatorBuilder::build_reschedule(self : OperatorBuilder[T, S], construct : (Array[Capability[T, S]]) -> (() -> Bool), on_shutdown? : () -> Unit) -> Unit

    Returning true keeps the operator alive for unfinished external work; it does not automatically schedule another invocation. Returning false permits shutdown once inputs are complete and output capabilities are released. on_shutdown is called exactly once on retirement or worker disposal, with re-entry forbidden.

    OperatorBuilder::new_input

    fn[D, T : Lattice + Compare + Eq, R, S] OperatorBuilder::new_input(self : OperatorBuilder[T, S], source : Collection[D, T, R]) -> OperatorInput[D, T, R, S]

    OperatorBuilder::new_output

    fn[D, T : Lattice + Compare + Eq, R, S] OperatorBuilder::new_output(self : OperatorBuilder[T, S]) -> (Output[D, T, R, S], Collection[D, T, R])

    OperatorBuilder::set_connection

    fn[D, E, T, R, U, S] OperatorBuilder::set_connection(self : OperatorBuilder[T, S], input : OperatorInput[D, T, R, S], output : Output[E, T, U, S], summaries : Array[S]) -> Unit

    Replace connectivity for this pair. Empty summaries disconnect progress and prohibit deriving output capabilities from this input. Multiple incomparable summaries are supported; each must be a lawful summary for the scope domain.

    OperatorEvent

    pub(all) enum OperatorEvent[D, T, R, S] {
    Data(Capability[T, S], Array[(D, R)])
    Progress(Antichain[T])
    }

    Data capabilities are borrowed for the callback: clone one to retain it. Progress describes the input frontier, excluding the output's held capabilities.

    OperatorInput

    pub struct OperatorInput[D, T, R, S] {
    // private fields
    }

    Input data and frontier owned by a custom operator. Call for_each only within that operator's build callback. The input capability is borrowed per batch.

    OperatorInput::for_each

    fn[D, T : Lattice + Compare + Eq, R, S] OperatorInput::for_each(self : OperatorInput[D, T, R, S], consume : (InputCapability[T, S], Array[(D, R)]) -> Unit) -> Unit

    Drain data and progress in arrival order. The frontier is current after this call; data callbacks see only the progress that preceded their data.

    OperatorInput::for_each_batch

    fn[D, T : Lattice + Compare + Eq, R, S] OperatorInput::for_each_batch(self : OperatorInput[D, T, R, S], consume : (InputCapability[T, S], Array[(D, T, R)]) -> Unit) -> Unit

    Drain original message containers with their borrowed input capability. Record timestamps are preserved separately and can be later than the capability time. Use Output.send_at to forward them without losing this distinction. for_each remains the convenience API grouped by record time.

    OperatorInput::frontier

    fn[D, T : Lattice + Compare + Eq, R, S] OperatorInput::frontier(self : OperatorInput[D, T, R, S]) -> Antichain[T]

    Output

    pub struct Output[D, T, R, S] {
    // private fields
    }

    Output port whose records require a live capability for this exact port.

    Output::accepts

    fn[D, T, R, S] Output::accepts(self : Output[D, T, R, S], capability : Capability[T, S]) -> Bool

    Output::send

    fn[D, T : Lattice + Compare + Eq, R, S] Output::send(self : Output[D, T, R, S], capability : Capability[T, S], records : Array[(D, R)]) -> Unit

    Output::send_at

    fn[D, T : Lattice + Compare + Eq, R, S] Output::send_at(self : Output[D, T, R, S], capability : Capability[T, S], records : Array[(D, T, R)]) -> Unit

    Each record's timestamp must be at or beyond the supplied capability.

    PointStamp

    pub struct PointStamp[T] {
    // private fields
    } derive(Eq,
    Debug
    )

    A runtime-length product timestamp. Missing coordinates are Timestamp.minimum; construction removes trailing minimum coordinates and copies the input array.
    impl Lattice for PointStamp[T]
    impl Timestamp for PointStamp[T]
    impl Compare for PointStamp[T]

    PointStamp::PointStamp

    fn[T : Timestamp + Lattice + Compare + Eq] PointStamp::PointStamp(vector : Array[T]) -> PointStamp[T]

    PointStamp::compare

    fn[T : Compare + Eq] PointStamp::compare(self : PointStamp[T], other : PointStamp[T]) -> Int

    PointStamp::equal

    fn[T : Eq] PointStamp::equal(PointStamp[T], PointStamp[T]) -> Bool

    PointStamp::join

    fn[T : Timestamp + Lattice + Compare + Eq] PointStamp::join(self : PointStamp[T], other : PointStamp[T]) -> PointStamp[T]

    PointStamp::less_equal

    fn[T : Timestamp + Lattice + Compare + Eq] PointStamp::less_equal(self : PointStamp[T], other : PointStamp[T]) -> Bool

    PointStamp::meet

    fn[T : Timestamp + Lattice + Compare + Eq] PointStamp::meet(self : PointStamp[T], other : PointStamp[T]) -> PointStamp[T]

    PointStamp::minimum

    fn[T : Timestamp + Lattice + Compare + Eq] PointStamp::minimum() -> PointStamp[T]

    PointStamp::not_equal

    fn[T : Eq] PointStamp::not_equal(x : PointStamp[T], y : PointStamp[T]) -> Bool

    PointStamp::op_ge

    fn[T : Compare + Eq] PointStamp::op_ge(x : PointStamp[T], y : PointStamp[T]) -> Bool

    PointStamp::op_gt

    fn[T : Compare + Eq] PointStamp::op_gt(x : PointStamp[T], y : PointStamp[T]) -> Bool

    PointStamp::op_le

    fn[T : Compare + Eq] PointStamp::op_le(x : PointStamp[T], y : PointStamp[T]) -> Bool

    PointStamp::op_lt

    fn[T : Compare + Eq] PointStamp::op_lt(x : PointStamp[T], y : PointStamp[T]) -> Bool

    PointStamp::to_array

    fn[T] PointStamp::to_array(self : PointStamp[T]) -> Array[T]

    PointStampSummary

    pub struct PointStampSummary[S] {
    // private fields
    } derive(Eq,
    Debug
    )

    Truncate to retain coordinates (None retains all), then apply per-coordinate actions, extending missing coordinates from the timestamp minimum as needed.

    PointStampSummary::PointStampSummary

    fn[S] PointStampSummary::PointStampSummary(actions : Array[S], retain? : Int) -> PointStampSummary[S]

    PointStampSummary::actions

    fn[S] PointStampSummary::actions(self : PointStampSummary[S]) -> Array[S]

    PointStampSummary::compare

    fn[S : Compare + Eq] PointStampSummary::compare(self : PointStampSummary[S], other : PointStampSummary[S]) -> Int

    PointStampSummary::equal

    PointStampSummary::not_equal

    fn[S : Eq] PointStampSummary::not_equal(x : PointStampSummary[S], y : PointStampSummary[S]) -> Bool

    PointStampSummary::op_ge

    fn[S : Compare + Eq] PointStampSummary::op_ge(x : PointStampSummary[S], y : PointStampSummary[S]) -> Bool

    PointStampSummary::op_gt

    fn[S : Compare + Eq] PointStampSummary::op_gt(x : PointStampSummary[S], y : PointStampSummary[S]) -> Bool

    PointStampSummary::op_le

    fn[S : Compare + Eq] PointStampSummary::op_le(x : PointStampSummary[S], y : PointStampSummary[S]) -> Bool

    PointStampSummary::op_lt

    fn[S : Compare + Eq] PointStampSummary::op_lt(x : PointStampSummary[S], y : PointStampSummary[S]) -> Bool

    PointStampSummary::retain

    fn[S] PointStampSummary::retain(self : PointStampSummary[S]) -> Int?

    Present

    pub(all) enum Present {
    Present
    } derive(Eq,
    Debug
    )

    Presence-only semigroup: there is no zero or retraction.

    Present::equal

    fn Present::equal(Present, Present) -> Bool

    Present::is_zero

    fn Present::is_zero(_self : Present) -> Bool

    Present::multiply

    fn[T] Present::multiply(_self : Present, value : T) -> T

    Present::not_equal

    fn Present::not_equal(x : Present, y : Present) -> Bool

    Present::plus

    fn Present::plus(self : Present, _other : Present) -> Present

    Present::to_repr

    Probe

    pub struct Probe[T] {
    // private fields
    }

    Probe::Probe

    fn[T] Probe::Probe() -> Probe[T]

    A shared progress handle, initially complete until a collection is attached with probe_with. Clone by retaining this handle; all attachments are shared.

    Probe::done

    fn[T] Probe::done(self : Probe[T]) -> Bool

    Probe::frontier

    fn[T : Lattice + Compare + Eq] Probe::frontier(self : Probe[T]) -> Antichain[T]

    Probe::less_equal

    fn[T : Lattice + Compare + Eq] Probe::less_equal(self : Probe[T], time : T) -> Bool

    Probe::less_than

    fn[T : Lattice + Compare + Eq] Probe::less_than(self : Probe[T], time : T) -> Bool

    Product

    pub(all) struct Product[A, B] {
    outer : A
    inner : B
    } derive(Compare, Eq,
    Debug
    )

    Product partial order; its Compare implementation is lexicographic.
    impl Lattice for Product[A, B]
    impl Timestamp for Product[A, B]

    Product::Product

    fn[A, B] Product::Product(outer : A, inner : B) -> Product[A, B]

    Product::compare

    fn[A : Compare + Eq, B : Compare + Eq] Product::compare(Product[A, B], Product[A, B]) -> Int

    Product::equal

    fn[A : Eq, B : Eq] Product::equal(Product[A, B], Product[A, B]) -> Bool

    Product::join

    fn[A : Lattice + Compare + Eq, B : Lattice + Compare + Eq] Product::join(self : Product[A, B], other : Product[A, B]) -> Product[A, B]

    Product::less_equal

    fn[A : Lattice + Compare + Eq, B : Lattice + Compare + Eq] Product::less_equal(self : Product[A, B], other : Product[A, B]) -> Bool

    Product::meet

    fn[A : Lattice + Compare + Eq, B : Lattice + Compare + Eq] Product::meet(self : Product[A, B], other : Product[A, B]) -> Product[A, B]

    Product::minimum

    fn[A : Timestamp + Lattice + Compare + Eq, B : Timestamp + Lattice + Compare + Eq] Product::minimum() -> Product[A, B]

    Product::not_equal

    fn[A : Eq, B : Eq] Product::not_equal(x : Product[A, B], y : Product[A, B]) -> Bool

    Product::op_ge

    fn[A : Compare + Eq, B : Compare + Eq] Product::op_ge(x : Product[A, B], y : Product[A, B]) -> Bool

    Product::op_gt

    fn[A : Compare + Eq, B : Compare + Eq] Product::op_gt(x : Product[A, B], y : Product[A, B]) -> Bool

    Product::op_le

    fn[A : Compare + Eq, B : Compare + Eq] Product::op_le(x : Product[A, B], y : Product[A, B]) -> Bool

    Product::op_lt

    fn[A : Compare + Eq, B : Compare + Eq] Product::op_lt(x : Product[A, B], y : Product[A, B]) -> Bool

    ProgressGraph

    pub struct ProgressGraph[T, S] {
    // private fields
    }

    Vertices represent individual operator ports; edges carry timestamp summaries.

    ProgressGraph::ProgressGraph

    fn[T, S] ProgressGraph::ProgressGraph(domain : SummaryDomain[T, S]) -> ProgressGraph[T, S]

    ProgressGraph::add_port

    fn[T, S] ProgressGraph::add_port(self : ProgressGraph[T, S]) -> Int

    ProgressGraph::compile

    fn[T, S : Compare + Eq] ProgressGraph::compile(self : ProgressGraph[T, S], max_steps? : Int) -> Reachability[T, S]?

    Compute the minimal summaries of all paths. None means the work bound was hit; a partial reachability graph is never returned as complete.

    ProgressGraph::connect

    fn[T, S] ProgressGraph::connect(self : ProgressGraph[T, S], source : Int, target : Int, summary : S) -> Unit

    ProgressTracker

    pub struct ProgressTracker[T, S] {
    // private fields
    }

    ProgressTracker::ProgressTracker

    fn[T : Lattice + Compare + Eq, S] ProgressTracker::ProgressTracker(reachability : Reachability[T, S]) -> ProgressTracker[T, S]

    ProgressTracker::capability

    fn[T : Lattice + Compare + Eq, S] ProgressTracker::capability(self : ProgressTracker[T, S], port : Int, time : T) -> Capability[T, S]

    ProgressTracker::frontier

    fn[T : Lattice + Compare + Eq, S] ProgressTracker::frontier(self : ProgressTracker[T, S], port : Int) -> Antichain[T]

    ProgressTracker::propagate

    fn[T : Lattice + Compare + Eq, S] ProgressTracker::propagate(self : ProgressTracker[T, S]) -> Array[(Int, T, Int64)]

    ProgressTracker::update

    fn[T : Lattice + Compare + Eq, S] ProgressTracker::update(self : ProgressTracker[T, S], port : Int, time : T, delta : Int64) -> Unit

    Queue a pointstamp count change. Frontier changes are published by propagate().

    Reachability

    pub struct Reachability[T, S] {
    // private fields
    }

    Reachability::port_count

    fn[T, S] Reachability::port_count(self : Reachability[T, S]) -> Int

    Reachability::summaries

    fn[T, S] Reachability::summaries(self : Reachability[T, S], source : Int, target : Int) -> Array[S]

    RefinedScope

    pub struct RefinedScope[A, B, S, U] {
    // private fields
    }

    RefinedScope::enter

    fn[D, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R, S, U] RefinedScope::enter(self : RefinedScope[A, B, S, U], source : Collection[D, A, R]) -> Collection[D, B, R]

    RefinedScope::enter_at

    fn[D, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R, S, U] RefinedScope::enter_at(self : RefinedScope[A, B, S, U], source : Collection[D, A, R], assign : (D, A) -> B) -> Collection[D, B, R]

    Assign data-dependent refined times, each at or beyond the lifted input time. Progress follows the lifted input frontier, independent of observed data.

    RefinedScope::leave

    fn[D, A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, R, S, U] RefinedScope::leave(self : RefinedScope[A, B, S, U], source : Collection[D, B, R]) -> Collection[D, A, R]

    RefinedScope::scope

    fn[A, B, S, U] RefinedScope::scope(self : RefinedScope[A, B, S, U]) -> Scope[B, U]

    Refinement

    pub struct Refinement[A, B, S, U] {
    // private fields
    }

    Explicit counterpart of Timely's Refines association. Functions must preserve the timestamp orders, project(lift(t)) == t, and agree with path-summary composition. User-defined refinements have the same law obligations as lattices.

    Refinement::Refinement

    fn[A, B, S, U] Refinement::Refinement(lift~ : (A) -> B, project~ : (B) -> A, summarize~ : (U) -> S) -> Refinement[A, B, S, U]

    Refinement::identity

    fn[T, S] Refinement::identity() -> Refinement[T, T, S, S]

    Refinement::product

    fn[A, B, S, U] Refinement::product(minimum : B) -> Refinement[A, Product[A, B], S, Product[S, U]]

    Refinement::summary_to_outer

    fn[A, B, S, U] Refinement::summary_to_outer(self : Refinement[A, B, S, U], summary : U) -> S

    Refinement::to_inner

    fn[A, B, S, U] Refinement::to_inner(self : Refinement[A, B, S, U], time : A) -> B

    Refinement::to_outer

    fn[A, B, S, U] Refinement::to_outer(self : Refinement[A, B, S, U], time : B) -> A

    ReplayInput

    pub struct ReplayInput[D, T, R] {
    // private fields
    }

    ReplayInput::cancel

    fn[D, T : Lattice + Compare + Eq, R] ReplayInput::cancel(self : ReplayInput[D, T, R]) -> Unit

    Cancel replay and discard incomplete intervals. Normal completion is signaled by a fully satisfied terminal progress message, not by calling cancel.

    ReplayInput::push

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Compare + Eq] ReplayInput::push(self : ReplayInput[D, T, R], message : CaptureMessage[D, T, R]) -> Unit

    Replayer

    pub struct Replayer[D, T, R] {
    // private fields
    }

    Reorders and deduplicates capture protocol messages. Missing updates keep progress pending even if their progress statements have already arrived.

    Replayer::Replayer

    fn[D, T : Lattice + Compare + Eq, R] Replayer::Replayer(minimum : T) -> Replayer[D, T, R]

    Replayer::frontier

    fn[D, T : Lattice + Compare + Eq, R] Replayer::frontier(self : Replayer[D, T, R]) -> Antichain[T]

    Replayer::push

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Compare + Eq] Replayer::push(self : Replayer[D, T, R], message : CaptureMessage[D, T, R]) -> (Array[(D, T, R)], Antichain[T])?

    Publish a newly completed interval, if this message makes one available. Duplicate records inside a single update message are also suppressed.

    RunResult

    pub(all) enum RunResult {
    Quiescent(Int)
    StepLimit(Int)
    } derive(Eq,
    Debug
    )

    RunResult::equal

    fn RunResult::equal(RunResult, RunResult) -> Bool

    RunResult::not_equal

    fn RunResult::not_equal(x : RunResult, y : RunResult) -> Bool

    Scope

    pub struct Scope[T, S] {
    // private fields
    }

    A timestamp domain with counted progress through cyclic operator graphs. Build all operators and feedback edges before sending data or stepping the worker.

    Scope::aggregate_ranges

    fn[K : Compare + Hash + Eq, D : Compare + Eq, T : Lattice + Compare + Eq, S : Compare + Eq] Scope::aggregate_ranges(self : Scope[T, S], source : Collection[((UInt64, K), D), T, Int64], combine : (K, D, D) -> D) -> Collection[((UInt64, Int, K), D), T, Int64]

    Accumulate every aligned power-of-two range. A key (position, log, key) represents [position * 2^log, (position + 1) * 2^log); log ranges from 0 to 64.

    Scope::bfs

    fn[N : Compare + Hash + Eq, T : Lattice + Compare + Eq, S : Compare + Eq] Scope::bfs(self : Scope[T, S], edges : Collection[(N, N), T, Int64], roots : Collection[N, T, Int64]) -> Collection[(N, UInt), T, Int64]

    Shortest unweighted distance from any root, maintained as edges and roots change. This follows upstream's iterative join-and-minimum formulation.

    Scope::bfs_arranged

    fn[N : Compare + Hash + Eq, T : Lattice + Compare + Eq, S : Compare + Eq] Scope::bfs_arranged(self : Scope[T, S], edges : ArrangementView[N, N, T, Int64], roots : Collection[N, T, Int64]) -> Collection[(N, UInt), T, Int64]

    Reuse an existing edge index for breadth-first distance labeling. The caller retains ownership of the supplied view.

    Scope::bidijkstra

    fn[N : Compare + Hash + Eq, T : Lattice + Compare + Eq, S : Compare + Eq] Scope::bidijkstra(self : Scope[T, S], graph : Collection[(N, N), T, Int64], goals : Collection[(N, N), T, Int64]) -> Collection[((N, N), UInt), T, Int64]

    Bidirectional shortest-path search for dynamic (source, target) goals. Results retain goal multiplicities; unreachable goals produce no record. Searches expand only while a goal involving their root is still unresolved.

    Scope::bidijkstra_arranged

    fn[N : Compare + Hash + Eq, T : Lattice + Compare + Eq, S : Compare + Eq] Scope::bidijkstra_arranged(self : Scope[T, S], forward : ArrangementView[N, N, T, Int64], reverse : ArrangementView[N, N, T, Int64], goals : Collection[(N, N), T, Int64]) -> Collection[((N, N), UInt), T, Int64]

    Reuse forward and reversed edge indexes for bidirectional search. The reverse index must describe the same weighted graph with its endpoints exchanged.

    Scope::broadcast_prefix

    fn[K : Compare + Hash + Eq, D : Compare + Hash + Eq, T : Lattice + Compare + Eq, S : Compare + Eq] Scope::broadcast_prefix(self : Scope[T, S], ranges : Collection[((UInt64, Int, K), D), T, Int64], queries : Collection[(UInt64, K), T, Int64], zero : D, combine : (K, D, D) -> D) -> Collection[((UInt64, K), D), T, Int64]

    Reconstruct exclusive prefixes from aligned ranges. Missing requested ranges contribute zero; repeated queries retain their multiplicity.

    Scope::capture_to

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup, S] Scope::capture_to(self : Scope[T, S], source : Collection[D, T, R], writer : CaptureWriter[D, T, R]) -> CaptureHandle

    Capture sealed, consolidated intervals through a retryable writer. Input continues to drain while writes are pending, as in upstream. A nonzero retry delay requires the worker's monotonic host clock. Wake the handle when done() changes asynchronously after all queued messages have been accepted.

    Scope::concatenate

    fn[D, T : Lattice + Compare + Eq, R, S] Scope::concatenate(self : Scope[T, S], sources : Array[Collection[D, T, R]]) -> Collection[D, T, R]

    Concatenate any number of collections, including an empty list. The empty result completes without requiring an input capability.

    Scope::dataflow_index

    fn[T, S] Scope::dataflow_index(self : Scope[T, S]) -> Int

    Scope::feedback

    fn[D, T : Lattice + Compare + Eq, R, S] Scope::feedback(self : Scope[T, S], summary : S) -> (Feedback[D, T, R, S], Collection[D, T, R])

    Scope::identifiers

    fn[D : Compare + RustHash + Eq, T : Lattice + Compare + Eq, R : Abelian + Monoid + Semigroup, S : Compare + Eq] Scope::identifiers(self : Scope[T, S], source : Collection[D, T, R]) -> Collection[(D, UInt64), T, R]

    Assign unique 64-bit identifiers using upstream's FNV hash and iterative collision resolution. Records compare by MoonBit Compare; custom Rust-ordered records should provide matching Compare and RustHash implementations.

    Scope::identifiers_with

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Abelian + Monoid + Semigroup, S : Compare + Eq] Scope::identifiers_with(self : Scope[T, S], source : Collection[D, T, R], hash : (Int, D) -> UInt64) -> Collection[(D, UInt64), T, R]

    Custom collision proposals. The hash must eventually admit distinct IDs as rounds increase; otherwise the fixed point need not converge.

    Scope::input

    fn[D, T : Lattice + Compare + Eq, R, S] Scope::input(self : Scope[T, S]) -> (InputSession[D, T, R], Collection[D, T, R])

    Scope::iterate

    fn[D, T : Lattice + Compare + Eq, R : Abelian + Monoid + Semigroup, S : Compare + Eq] Scope::iterate(self : Scope[T, S], source : Collection[D, T, R], logic : (Scope[Product[T, Int64], Product[S, Int64]], Collection[D, Product[T, Int64], R]) -> Collection[D, Product[T, Int64], R]) -> Collection[D, T, R]

    Iteration uses a nested Int64 coordinate starting at zero and advancing by one. The returned collection contains changes to the fixed point at each outer time.

    Scope::leave_dynamic

    fn[D, A : Lattice + Compare + Eq, B : Timestamp + Lattice + Compare + Eq, R, S, U] Scope::leave_dynamic(self : Scope[Product[A, PointStamp[B]], Product[S, PointStampSummary[U]]], source : Collection[D, Product[A, PointStamp[B]], R], level : Int) -> Collection[D, Product[A, PointStamp[B]], R]

    Leave the one-based dynamic level, discarding that and deeper coordinates.

    Scope::nested

    fn[A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, S : Compare + Eq, U : Compare + Eq] Scope::nested(self : Scope[A, S], minimum : B, domain : SummaryDomain[B, U]) -> NestedScope[A, B, S, U]

    Scope::operator

    fn[T, S] Scope::operator(self : Scope[T, S]) -> OperatorBuilder[T, S]

    Scope::prefix_sum

    fn[K : Compare + Hash + Eq, D : Compare + Hash + Eq, T : Lattice + Compare + Eq, S : Compare + Eq] Scope::prefix_sum(self : Scope[T, S], source : Collection[((UInt64, K), D), T, Int64], zero : D, combine : (K, D, D) -> D) -> Collection[((UInt64, K), D), T, Int64]

    Exclusive prefix accumulation at each input location. Positions are 64-bit unsigned integers (the upstream 64-bit usize domain). Each key is independent. The input must describe at most one value per (position, key); combine must be associative with the supplied zero, and need not be commutative.

    Scope::prefix_sum_at

    fn[K : Compare + Hash + Eq, D : Compare + Hash + Eq, T : Lattice + Compare + Eq, S : Compare + Eq] Scope::prefix_sum_at(self : Scope[T, S], source : Collection[((UInt64, K), D), T, Int64], locations : Collection[(UInt64, K), T, Int64], zero : D, combine : (K, D, D) -> D) -> Collection[((UInt64, K), D), T, Int64]

    Exclusive prefix values at arbitrary query locations, including empty ranges. Output multiplicities follow the query collection.

    Scope::propagate

    fn[N : Compare + Hash + Eq, L : Compare + Eq, T : Lattice + Compare + Eq, S : Compare + Eq, R : Ring + Abelian + Monoid + Semigroup] Scope::propagate(self : Scope[T, S], edges : Collection[(N, N), T, R], nodes : Collection[(N, L), T, R]) -> Collection[(N, L), T, R]

    Forward propagation of the minimum label reachable at each node.

    Scope::propagate_at

    fn[N : Compare + Hash + Eq, L : Compare + Eq, T : Lattice + Compare + Eq, S : Compare + Eq, R : Ring + Abelian + Monoid + Semigroup] Scope::propagate_at(self : Scope[T, S], edges : Collection[(N, N), T, R], nodes : Collection[(N, L), T, R], priority : (L) -> UInt64) -> Collection[(N, L), T, R]

    Stagger label introduction with upstream's 256 * bit_length(priority) schedule. Scheduling affects intermediate work; converged labels retain original times.

    Scope::propagate_core

    fn[N : Compare + Hash + Eq, L : Compare + Eq, T : Lattice + Compare + Eq, S : Compare + Eq, R : Ring + Abelian + Monoid + Semigroup] Scope::propagate_core(self : Scope[T, S], edges : ArrangementView[N, N, T, R], nodes : Collection[(N, L), T, R], priority : (L) -> UInt64) -> Collection[(N, L), T, R]

    Propagate labels using a shared edge index and reuse the reduced label index in the feedback join. Priority controls label introduction as in propagate_at.

    Scope::refine

    fn[A, B : Lattice + Compare + Eq, S, U : Compare + Eq] Scope::refine(self : Scope[A, S], domain : SummaryDomain[B, U], refinement : Refinement[A, B, S, U]) -> RefinedScope[A, B, S, U]

    Scope::region

    fn[T : Lattice + Compare + Eq, S : Compare + Eq] Scope::region(self : Scope[T, S]) -> RefinedScope[T, T, S, S]

    A nested region with identical timestamps and summaries.

    Scope::replay

    fn[D, T : Lattice + Compare + Eq, R, S] Scope::replay(self : Scope[T, S]) -> (ReplayInput[D, T, R], Collection[D, T, R])

    Scope::replay_from

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Compare + Eq, S] Scope::replay_from(self : Scope[T, S], build_source : (Activator) -> (() -> CaptureMessage[D, T, R]?), messages_per_turn? : Int) -> (CaptureHandle, Collection[D, T, R])

    Poll an external message source in bounded turns. None means temporarily empty, not EOF: normal completion requires the terminal capture progress statement. Unique data/time pairs are emitted eagerly, as in upstream capture::source; conflicting differences for one pair are rejected. The source builder receives an activator for future arrivals.

    Scope::sequence

    fn[N : Compare + Hash + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, S : Compare + Eq] Scope::sequence(self : Scope[T, S], state : Collection[(N, V), T, Int64], edges : Collection[(N, N), T, Int64], logic : (N, Array[(V, Int64)]) -> V) -> Collection[(N, V?), T, Int64]

    One sequential update of node states in Compare order. Lower neighbors supply their new state; higher neighbors supply their input state. As upstream, nodes with no incoming messages are absent from the result, and self-edges are ignored.

    Scope::source

    fn[D, T : Lattice + Compare + Eq, R, S] Scope::source(self : Scope[T, S]) -> (Output[D, T, R, S], Capability[T, S], Collection[D, T, R])

    Create a manually driven source. Release every cloned capability to finish it.

    Scope::strongly_connected

    fn[N : Compare + Hash + Eq, T : Lattice + Compare + Eq, S : Compare + Eq, R : Ring + Abelian + Monoid + Semigroup] Scope::strongly_connected(self : Scope[T, S], graph : Collection[(N, N), T, R]) -> Collection[(N, N), T, R]

    Keep precisely the original edges whose endpoints are in the same strongly connected component. Edge weights are retained; this is not a component-ID map.

    Scope::strongly_connected_at

    fn[N : Compare + Hash + Eq, T : Lattice + Compare + Eq, S : Compare + Eq, R : Ring + Abelian + Monoid + Semigroup] Scope::strongly_connected_at(self : Scope[T, S], graph : Collection[(N, N), T, R], priority : (N) -> UInt64) -> Collection[(N, N), T, R]

    Scope::unary

    fn[D, E, T : Lattice + Compare + Eq, R, U, S] Scope::unary(self : Scope[T, S], source : Collection[D, T, R], build : (Output[E, T, U, S], Capability[T, S]) -> ((OperatorEvent[D, T, R, S]) -> Unit)) -> Collection[E, T, U]

    Build a frontier-aware unary operator with identity timestamp connectivity. The builder receives an initial owned capability; release it when no longer needed. Data callbacks receive a borrowed capability valid for the output port.

    Scope::variable

    fn[D, T : Lattice + Compare + Eq, R, S] Scope::variable(self : Scope[T, S], step : S) -> (Variable[D, T, R, S], Collection[D, T, R])

    Scope::variable_from

    fn[D, T : Lattice + Compare + Eq, R : Abelian + Monoid + Semigroup, S] Scope::variable_from(self : Scope[T, S], source : Collection[D, T, R], step : S) -> (Variable[D, T, R, S], Collection[D, T, R])

    ScopeGroup

    pub struct ScopeGroup[T, S] {
    // private fields
    }

    Identical operator graphs with globally counted pointstamps across peer workers.

    ScopeGroup::dataflow_index

    fn[T, S] ScopeGroup::dataflow_index(self : ScopeGroup[T, S]) -> Int

    ScopeGroup::exchange

    fn[D, T : Lattice + Compare + Eq, R, S] ScopeGroup::exchange(self : ScopeGroup[T, S], inputs : Array[Collection[D, T, R]], hash : (D) -> UInt64) -> Array[Collection[D, T, R]]

    Route each record to hash(data) % peers. Connectivity and message counts are shared across peers, so an idle peer cannot report another peer's time complete.

    ScopeGroup::input

    fn[D, T : Lattice + Compare + Eq, R, S] ScopeGroup::input(self : ScopeGroup[T, S]) -> Array[(InputSession[D, T, R], Collection[D, T, R])]

    ScopeGroup::iterate

    fn[D, T : Lattice + Compare + Eq, R : Abelian + Monoid + Semigroup, S : Compare + Eq] ScopeGroup::iterate(self : ScopeGroup[T, S], sources : Array[Collection[D, T, R]], logic : (ScopeGroup[Product[T, Int64], Product[S, Int64]], Array[Collection[D, Product[T, Int64], R]]) -> Array[Collection[D, Product[T, Int64], R]]) -> Array[Collection[D, T, R]]

    Build a fixed point over all peers. Use the child group's exchange method to colocate equal keys before keyed operators inside the iterative computation.

    ScopeGroup::nested

    fn[A : Lattice + Compare + Eq, B : Lattice + Compare + Eq, S : Compare + Eq, U : Compare + Eq] ScopeGroup::nested(self : ScopeGroup[A, S], minimum : B, domain : SummaryDomain[B, U]) -> NestedScopeGroup[A, B, S, U]

    ScopeGroup::replay_from

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Compare + Eq, S] ScopeGroup::replay_from(self : ScopeGroup[T, S], build_source : (Int, Activator) -> (() -> CaptureMessage[D, T, R]?), hash~ : (D) -> UInt64, time_hash? : (T) -> UInt64, messages_per_turn? : Int) -> Array[(CaptureHandle, Collection[D, T, R])]

    Replay one captured collection from sources scattered across peers. Unique data/time pairs are emitted immediately on hash(data) % peers; conflicting differences are rejected. Timestamp counts are sharded by time_hash (default peer zero). Progress is global, so a paused source cannot imply completion.

    ScopeGroup::scope

    fn[T, S] ScopeGroup::scope(self : ScopeGroup[T, S], index : Int) -> Scope[T, S]

    SingletonDiff

    pub struct SingletonDiff[R] {
    // private fields
    } derive(Compare, Eq, Hash,
    Debug
    )

    MoonBit counterpart of Rust's one-element difference tuple (R,).
    impl Monoid for SingletonDiff[R]

    SingletonDiff::SingletonDiff

    fn[R] SingletonDiff::SingletonDiff(value : R) -> SingletonDiff[R]

    SingletonDiff::compare

    fn[R : Compare + Eq] SingletonDiff::compare(SingletonDiff[R], SingletonDiff[R]) -> Int

    SingletonDiff::equal

    fn[R : Eq] SingletonDiff::equal(SingletonDiff[R], SingletonDiff[R]) -> Bool

    SingletonDiff::hash

    fn[R : Hash] SingletonDiff::hash(self : SingletonDiff[R]) -> Int

    SingletonDiff::hash_combine

    fn[R : Hash] SingletonDiff::hash_combine(SingletonDiff[R], Hasher) -> Unit

    SingletonDiff::is_zero

    fn[R : Semigroup] SingletonDiff::is_zero(self : SingletonDiff[R]) -> Bool

    SingletonDiff::negate

    fn[R : Abelian + Monoid + Semigroup] SingletonDiff::negate(self : SingletonDiff[R]) -> SingletonDiff[R]

    SingletonDiff::not_equal

    fn[R : Eq] SingletonDiff::not_equal(x : SingletonDiff[R], y : SingletonDiff[R]) -> Bool

    SingletonDiff::op_ge

    fn[R : Compare + Eq] SingletonDiff::op_ge(x : SingletonDiff[R], y : SingletonDiff[R]) -> Bool

    SingletonDiff::op_gt

    fn[R : Compare + Eq] SingletonDiff::op_gt(x : SingletonDiff[R], y : SingletonDiff[R]) -> Bool

    SingletonDiff::op_le

    fn[R : Compare + Eq] SingletonDiff::op_le(x : SingletonDiff[R], y : SingletonDiff[R]) -> Bool

    SingletonDiff::op_lt

    fn[R : Compare + Eq] SingletonDiff::op_lt(x : SingletonDiff[R], y : SingletonDiff[R]) -> Bool

    SingletonDiff::plus

    fn[R : Semigroup] SingletonDiff::plus(self : SingletonDiff[R], other : SingletonDiff[R]) -> SingletonDiff[R]

    SingletonDiff::scale

    fn[R, S, O] SingletonDiff::scale(self : SingletonDiff[R], scalar : S, multiply : (R, S) -> O) -> SingletonDiff[O]

    SingletonDiff::value

    fn[R] SingletonDiff::value(self : SingletonDiff[R]) -> R

    SingletonDiff::zero

    SpillPolicy

    pub struct SpillPolicy[D, T, R] {
    // private fields
    }

    Explicit per-worker high-water-mark policy. Resident budget is not reclaimed when old batches disappear, matching upstream. Readers cache at most one page each; counters are cumulative. The codec is an application-selected encoding.

    SpillPolicy::SpillPolicy

    fn[D, T, R] SpillPolicy::SpillPolicy(budget_records : Int64, store~ : BytesStore, codec~ : WireCodec[Array[(D, T, R)]], chunk_size? : Int) -> SpillPolicy[D, T, R]

    SpillPolicy::binary

    fn[D, T, R] SpillPolicy::binary(budget_records : Int64, store~ : BytesStore, encode~ : (Array[(D, T, R)]) -> Bytes, decode~ : (BytesView) -> Array[(D, T, R)]?, chunk_size? : Int) -> SpillPolicy[D, T, R]

    Install an application-selected binary page codec. Encode/decode must preserve sorted consolidated updates exactly; paging still validates length/checksum.

    SpillPolicy::stats

    fn[D, T, R] SpillPolicy::stats(self : SpillPolicy[D, T, R]) -> SpillStats

    SpillStats

    pub(all) struct SpillStats {
    spilled_chunks : Int64
    spilled_records : Int64
    fetched_chunks : Int64
    bytes_written : Int64
    resident_records : Int64
    } derive(Eq,
    Debug
    )

    SpillStats::equal

    fn SpillStats::equal(SpillStats, SpillStats) -> Bool

    SpillStats::not_equal

    fn SpillStats::not_equal(x : SpillStats, y : SpillStats) -> Bool

    Spine

    pub struct Spine[D, T, R] {
    // private fields
    }

    A fueled spine of immutable batches. Reader cuts remain available until the physical frontier permits merging. In-progress merges retain both sources; a completed merge replaces them atomically, so cursors keep stable storage.

    Spine::Spine

    fn[D, T : Lattice + Compare + Eq, R] Spine::Spine(minimum : T, logger? : TraceLogger) -> Spine[D, T, R]

    Spine::advance_upper

    fn[D, T : Lattice + Compare + Eq, R] Spine::advance_upper(self : Spine[D, T, R], upper : Antichain[T]) -> Antichain[T]

    Spine::batches_through

    fn[D, T : Lattice + Compare + Eq, R] Spine::batches_through(self : Spine[D, T, R], upper : Antichain[T]) -> Array[Batch[D, T, R]]?

    Spine::close

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Spine::close(self : Spine[D, T, R]) -> Unit

    Spine::cursor

    fn[K : Compare + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, R] Spine::cursor(self : Spine[(K, V), T, R]) -> Cursor[K, V, T, R]

    Spine::cursor_through

    fn[K : Compare + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, R] Spine::cursor_through(self : Spine[(K, V), T, R], upper : Antichain[T]) -> Cursor[K, V, T, R]?

    Spine::dispose

    fn[D, T : Lattice + Compare + Eq, R] Spine::dispose(self : Spine[D, T, R]) -> Unit

    Abandon outstanding merge work and release all retained standalone storage.

    Spine::exert

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Spine::exert(self : Spine[D, T, R]) -> Unit

    Spine::exert_with_fuel

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Spine::exert_with_fuel(self : Spine[D, T, R], fuel : Int) -> Int

    Perform bounded merge work, returning remaining fuel. As for BatchMerger, one data group may overshoot the budget. Input batches remain queryable.

    Spine::insert

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Spine::insert(self : Spine[D, T, R], batch : Batch[D, T, R]) -> Unit

    Spine::levels

    fn[D, T, R] Spine::levels(self : Spine[D, T, R]) -> Array[(Int, Int, Int)]

    Spine::logical_compaction

    fn[D, T : Lattice + Compare + Eq, R] Spine::logical_compaction(self : Spine[D, T, R]) -> Antichain[T]

    Spine::map_batches

    fn[D, T, R] Spine::map_batches(self : Spine[D, T, R], visit : (Batch[D, T, R]) -> Unit) -> Unit

    Spine::physical_compaction

    fn[D, T : Lattice + Compare + Eq, R] Spine::physical_compaction(self : Spine[D, T, R]) -> Antichain[T]

    Spine::set_exert_logic

    fn[D, T, R] Spine::set_exert_logic(self : Spine[D, T, R], logic : (Array[(Int, Int, Int)]) -> Int?) -> Unit

    Exertion receives occupied levels, largest first, as (level, batch count, update count). Returning None or nonpositive fuel declines background work.

    Spine::set_logical_compaction

    fn[D, T : Lattice + Compare + Eq, R] Spine::set_logical_compaction(self : Spine[D, T, R], frontier : Antichain[T]) -> Unit

    Spine::set_physical_compaction

    fn[D, T : Lattice + Compare + Eq, R] Spine::set_physical_compaction(self : Spine[D, T, R], frontier : Antichain[T]) -> Unit

    Spine::snapshot

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Spine::snapshot(self : Spine[D, T, R], time : T) -> Array[(D, R)]

    Spine::upper

    fn[D, T : Lattice + Compare + Eq, R] Spine::upper(self : Spine[D, T, R]) -> Antichain[T]

    SummaryDomain

    pub struct SummaryDomain[T, S] {
    // private fields
    }

    Explicit timestamp/summary association, replacing Rust's associated Summary type. Functions must obey Timely's monotonicity, identity and composition laws.

    SummaryDomain::SummaryDomain

    fn[T, S] SummaryDomain::SummaryDomain(identity : S, apply~ : (S, T) -> T?, compose~ : (S, S) -> S?, less_equal~ : (S, S) -> Bool) -> SummaryDomain[T, S]

    SummaryDomain::byte

    fn SummaryDomain::byte() -> SummaryDomain[Byte, Byte]

    SummaryDomain::duration

    SummaryDomain::feedback_summary

    fn[T, S] SummaryDomain::feedback_summary(self : SummaryDomain[T, S], level : Int, action : S) -> PointStampSummary[S]

    Feedback at a one-based runtime scope level; earlier coordinates are unchanged.

    SummaryDomain::followed_by

    fn[T, S] SummaryDomain::followed_by(self : SummaryDomain[T, S], first : S, second : S) -> S?

    SummaryDomain::identity

    fn[T, S] SummaryDomain::identity(self : SummaryDomain[T, S]) -> S

    SummaryDomain::int128

    SummaryDomain::int16

    fn SummaryDomain::int16() -> SummaryDomain[Int16, Int16]

    SummaryDomain::int32

    fn SummaryDomain::int32() -> SummaryDomain[Int, Int]

    SummaryDomain::int64

    fn SummaryDomain::int64() -> SummaryDomain[Int64, Int64]

    SummaryDomain::int8

    SummaryDomain::pointstamp

    fn[T : Timestamp + Lattice + Compare + Eq, S] SummaryDomain::pointstamp(inner : SummaryDomain[T, S]) -> SummaryDomain[PointStamp[T], PointStampSummary[S]]

    SummaryDomain::product

    fn[A, B, S, U] SummaryDomain::product(outer : SummaryDomain[A, S], inner : SummaryDomain[B, U]) -> SummaryDomain[Product[A, B], Product[S, U]]

    SummaryDomain::results_in

    fn[T, S] SummaryDomain::results_in(self : SummaryDomain[T, S], summary : S, time : T) -> T?

    SummaryDomain::uint128

    SummaryDomain::uint16

    fn SummaryDomain::uint16() -> SummaryDomain[UInt16, UInt16]

    SummaryDomain::uint32

    fn SummaryDomain::uint32() -> SummaryDomain[UInt, UInt]

    SummaryDomain::uint64

    fn SummaryDomain::uint64() -> SummaryDomain[UInt64, UInt64]

    SummaryDomain::unit

    fn SummaryDomain::unit() -> SummaryDomain[Unit, Unit]

    Trace

    pub struct Trace[D, T, R] {
    // private fields
    }

    Ordered batches with independent logical and physical compaction frontiers.

    Trace::Trace

    fn[D, T : Lattice + Compare + Eq, R] Trace::Trace(minimum : T, logger? : TraceLogger) -> Trace[D, T, R]

    Trace::advance_upper

    fn[D, T : Lattice + Compare + Eq, R] Trace::advance_upper(self : Trace[D, T, R], upper : Antichain[T]) -> Antichain[T]

    Advance a supplied bound across consecutive empty intervals without mutating it.

    Trace::batches_through

    fn[D, T : Lattice + Compare + Eq, R] Trace::batches_through(self : Trace[D, T, R], upper : Antichain[T]) -> Array[Batch[D, T, R]]?

    Return an exact batch cut, or None when physical compaction removed it.

    Trace::close

    fn[D, T : Lattice + Compare + Eq, R] Trace::close(self : Trace[D, T, R]) -> Unit

    Seal the remaining interval with an empty batch. Repeated close is harmless.

    Trace::cursor

    fn[K : Compare + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, R] Trace::cursor(self : Trace[(K, V), T, R]) -> Cursor[K, V, T, R]

    Trace::cursor_through

    fn[K : Compare + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, R] Trace::cursor_through(self : Trace[(K, V), T, R], upper : Antichain[T]) -> Cursor[K, V, T, R]?

    Trace::dispose

    fn[D, T : Lattice + Compare + Eq, R] Trace::dispose(self : Trace[D, T, R]) -> Unit

    Release retained batches and close a standalone trace. Shared traces instead release storage through their independently owned TraceAgent handles.

    Trace::insert

    fn[D, T : Lattice + Compare + Eq, R] Trace::insert(self : Trace[D, T, R], batch : Batch[D, T, R]) -> Unit

    Trace::logical_compaction

    fn[D, T : Lattice + Compare + Eq, R] Trace::logical_compaction(self : Trace[D, T, R]) -> Antichain[T]

    Trace::map_batches

    fn[D, T, R] Trace::map_batches(self : Trace[D, T, R], visit : (Batch[D, T, R]) -> Unit) -> Unit

    Visit retained batches in interval order, including empty progress batches.

    Trace::physical_compaction

    fn[D, T : Lattice + Compare + Eq, R] Trace::physical_compaction(self : Trace[D, T, R]) -> Antichain[T]

    Trace::set_logical_compaction

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Trace::set_logical_compaction(self : Trace[D, T, R], frontier : Antichain[T]) -> Unit

    Permit changing update times while preserving all queries beyond this frontier.

    Trace::set_physical_compaction

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Trace::set_physical_compaction(self : Trace[D, T, R], frontier : Antichain[T]) -> Unit

    Permit merging batch boundaries no longer needed by readers.

    Trace::snapshot

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] Trace::snapshot(self : Trace[D, T, R], time : T) -> Array[(D, R)]

    Consolidated snapshot at a completed timestamp, subject to the logical frontier.

    Trace::upper

    fn[D, T : Lattice + Compare + Eq, R] Trace::upper(self : Trace[D, T, R]) -> Antichain[T]

    TraceAgent

    pub struct TraceAgent[D, T, R] {
    // private fields
    }

    An independently owned trace reader. Clone to retain a separate compaction capability, and release explicitly when the reader is no longer needed.

    TraceAgent::advance_upper

    fn[D, T : Lattice + Compare + Eq, R] TraceAgent::advance_upper(self : TraceAgent[D, T, R], upper : Antichain[T]) -> Antichain[T]

    TraceAgent::batches_through

    fn[D, T : Lattice + Compare + Eq, R] TraceAgent::batches_through(self : TraceAgent[D, T, R], upper : Antichain[T]) -> Array[Batch[D, T, R]]?

    TraceAgent::clone

    fn[D, T : Lattice + Compare + Eq, R] TraceAgent::clone(self : TraceAgent[D, T, R]) -> TraceAgent[D, T, R]

    TraceAgent::cursor

    fn[K : Compare + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, R] TraceAgent::cursor(self : TraceAgent[(K, V), T, R]) -> Cursor[K, V, T, R]

    TraceAgent::cursor_through

    fn[K : Compare + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, R] TraceAgent::cursor_through(self : TraceAgent[(K, V), T, R], upper : Antichain[T]) -> Cursor[K, V, T, R]?

    TraceAgent::exert

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] TraceAgent::exert(self : TraceAgent[D, T, R]) -> Unit

    TraceAgent::import_into

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup, S] TraceAgent::import_into(self : TraceAgent[D, T, R], scope : Scope[T, S]) -> Collection[D, T, R]

    Import through an independent storage-neutral reader capability.

    TraceAgent::logical_compaction

    fn[D, T : Lattice + Compare + Eq, R] TraceAgent::logical_compaction(self : TraceAgent[D, T, R]) -> Antichain[T]

    TraceAgent::lookup

    fn[K : Compare + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup, Q, O] TraceAgent::lookup(self : TraceAgent[(K, V), T, R], queries : Collection[(K, T), T, Q], multiply~ : (R, Q) -> O) -> Collection[(K, V), T, O]

    Answer timestamped key queries after the trace seals the requested time. Query data is (key, snapshot_time); results retain the query's stream timestamp. The reader pins historical data until queries finish or their worker is disposed.

    TraceAgent::lookup_at

    fn[K : Compare + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] TraceAgent::lookup_at(self : TraceAgent[(K, V), T, R], key : K, time : T) -> Array[(V, R)]

    Read a key at a completed timestamp, subject to this reader's logical frontier.

    TraceAgent::map_batches

    fn[D, T, R] TraceAgent::map_batches(self : TraceAgent[D, T, R], visit : (Batch[D, T, R]) -> Unit) -> Unit

    TraceAgent::physical_compaction

    fn[D, T : Lattice + Compare + Eq, R] TraceAgent::physical_compaction(self : TraceAgent[D, T, R]) -> Antichain[T]

    TraceAgent::reader

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] TraceAgent::reader(self : TraceAgent[D, T, R]) -> TraceReader[D, T, R]

    Retain a storage-independent reader over this shared trace.

    TraceAgent::release

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] TraceAgent::release(self : TraceAgent[D, T, R]) -> Unit

    TraceAgent::set_logical_compaction

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] TraceAgent::set_logical_compaction(self : TraceAgent[D, T, R], frontier : Antichain[T]) -> Unit

    TraceAgent::set_physical_compaction

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] TraceAgent::set_physical_compaction(self : TraceAgent[D, T, R], frontier : Antichain[T]) -> Unit

    TraceAgent::snapshot

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] TraceAgent::snapshot(self : TraceAgent[D, T, R], time : T) -> Array[(D, R)]

    TraceAgent::upper

    fn[D, T : Lattice + Compare + Eq, R] TraceAgent::upper(self : TraceAgent[D, T, R]) -> Antichain[T]

    TraceBackend

    pub struct TraceBackend[D, T, R] {
    // private fields
    }

    A custom arrangement writer and its initial independently owned reader. close must seal the trace at the empty upper frontier and notify imports; the wrapper calls it at most once. The writer must not release the reader.

    TraceBackend::TraceBackend

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] TraceBackend::TraceBackend(reader : TraceReader[D, T, R], insert~ : (BatchView[D, T, R]) -> Unit, close~ : () -> Unit, build? : (Array[(D, T, R)], Description[T]) -> BatchView[D, T, R]) -> TraceBackend[D, T, R]

    TraceLogger

    pub struct TraceLogger {
    // private fields
    }

    Bind trace diagnostics to a worker-local operator identity.

    TraceLogger::TraceLogger

    fn TraceLogger::TraceLogger(logger : Logger[DifferentialEvent], operator~ : Int) -> TraceLogger

    TraceReader

    pub struct TraceReader[D, T, R] {
    // private fields
    }

    A trace-reader capability independent of storage and timestamp representation. Clone retains an independent compaction capability. Release explicitly.

    TraceReader::TraceReader

    fn[D, T, R] TraceReader::TraceReader(clone_reader~ : () -> TraceReader[D, T, R], release_reader~ : () -> Unit, upper~ : () -> Antichain[T], logical_compaction~ : () -> Antichain[T], physical_compaction~ : () -> Antichain[T], set_logical_compaction~ : (Antichain[T]) -> Unit, set_physical_compaction~ : (Antichain[T]) -> Unit, batches_through~ : (Antichain[T]) -> Array[BatchView[D, T, R]]?, subscribe~ : ((BatchView[D, T, R]) -> Unit) -> (() -> Unit)) -> TraceReader[D, T, R]

    Adapt a custom trace implementation to the storage-neutral reader interface. clone_reader must acquire an independent compaction pin; release_reader drops this pin once. Frontiers and returned batch arrays must be owned snapshots. batches_through must reject unavailable clean cuts. subscribe registers future sealed batches and returns an idempotent cancellation function. Implementors must enforce monotone compaction, preserve immutable retained batches, and notify listeners only after making a newly sealed batch visible to reads.

    TraceReader::advance_upper

    fn[D, T : Lattice + Compare + Eq, R] TraceReader::advance_upper(self : TraceReader[D, T, R], upper : Antichain[T]) -> Antichain[T]

    TraceReader::batches_through

    fn[D, T, R] TraceReader::batches_through(self : TraceReader[D, T, R], upper : Antichain[T]) -> Array[BatchView[D, T, R]]?

    TraceReader::clone

    fn[D, T, R] TraceReader::clone(self : TraceReader[D, T, R]) -> TraceReader[D, T, R]

    TraceReader::cursor

    fn[K : Compare + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, R] TraceReader::cursor(self : TraceReader[(K, V), T, R]) -> Cursor[K, V, T, R]

    TraceReader::cursor_through

    fn[K : Compare + Eq, V : Compare + Eq, T, R] TraceReader::cursor_through(self : TraceReader[(K, V), T, R], upper : Antichain[T]) -> Cursor[K, V, T, R]?

    TraceReader::enter

    fn[D, T : Lattice + Compare + Eq, U : Lattice + Compare + Eq, R] TraceReader::enter(self : TraceReader[D, T, R], minimum : U) -> TraceReader[D, Product[T, U], R]

    TraceReader::frontier

    fn[D, T : Lattice + Compare + Eq, R] TraceReader::frontier(self : TraceReader[D, T, R], since : Antichain[T], until : Antichain[T]) -> TraceReader[D, T, R]

    Retain a frontier-filtered trace view. Compaction capabilities and batch cuts still refer to the backing trace, exactly as for upstream TraceFrontier.

    TraceReader::import_arranged

    fn[K : Compare + Eq, V : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup, S] TraceReader::import_arranged(self : TraceReader[(K, V), T, R], scope : Scope[T, S]) -> ArrangementView[K, V, T, R]

    Import a custom or built-in keyed trace while retaining an independent reader for indexed downstream operators. Both the import and returned view own pins.

    TraceReader::import_into

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup, S] TraceReader::import_into(self : TraceReader[D, T, R], scope : Scope[T, S]) -> Collection[D, T, R]

    Import a trace's retained state and subsequent sealed batches into a scope. The imported data represents snapshots at or beyond this reader's logical frontier. Its independent reader is released on closure or worker disposal.

    TraceReader::logical_compaction

    fn[D, T, R] TraceReader::logical_compaction(self : TraceReader[D, T, R]) -> Antichain[T]

    TraceReader::map_batches

    fn[D, T : Lattice + Compare + Eq, R] TraceReader::map_batches(self : TraceReader[D, T, R], visit : (BatchView[D, T, R]) -> Unit) -> Unit

    TraceReader::physical_compaction

    fn[D, T, R] TraceReader::physical_compaction(self : TraceReader[D, T, R]) -> Antichain[T]

    TraceReader::refine

    fn[D, T : Lattice + Compare + Eq, U : Lattice + Compare + Eq, R] TraceReader::refine(self : TraceReader[D, T, R], lift~ : (T) -> U, project~ : (U) -> T) -> TraceReader[D, U, R]

    Retain a view in a refined timestamp domain. Frontiers and exact batch cuts project into the backing reader; returned compaction bounds are lifted back, matching upstream TraceEnter. The functions must satisfy refinement laws.

    TraceReader::refine_at

    fn[D, T : Lattice + Compare + Eq, U : Lattice + Compare + Eq, R] TraceReader::refine_at(self : TraceReader[D, T, R], lift~ : (T) -> U, project~ : (U) -> T, assign~ : (D, T) -> U, prior~ : (U) -> T) -> TraceReader[D, U, R]

    Retain a data-dependent timestamp view. Exact cuts use project; compaction capabilities use prior, which must conservatively invert the assignment.

    TraceReader::release

    fn[D, T, R] TraceReader::release(self : TraceReader[D, T, R]) -> Unit

    TraceReader::set_logical_compaction

    fn[D, T, R] TraceReader::set_logical_compaction(self : TraceReader[D, T, R], frontier : Antichain[T]) -> Unit

    TraceReader::set_physical_compaction

    fn[D, T, R] TraceReader::set_physical_compaction(self : TraceReader[D, T, R], frontier : Antichain[T]) -> Unit

    TraceReader::snapshot

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] TraceReader::snapshot(self : TraceReader[D, T, R], time : T) -> Array[(D, R)]

    TraceReader::subscribe

    fn[D, T, R] TraceReader::subscribe(self : TraceReader[D, T, R], notify : (BatchView[D, T, R]) -> Unit) -> (() -> Unit)

    Subscribe to future sealed batches. Retained batches are not replayed. Cancel the subscription explicitly before releasing its reader.

    TraceReader::upper

    fn[D, T, R] TraceReader::upper(self : TraceReader[D, T, R]) -> Antichain[T]

    TraceShare

    pub(all) struct TraceShare {
    operator : Int
    diff : Int
    } derive(Eq,
    Debug
    )

    TraceShare::equal

    fn TraceShare::equal(TraceShare, TraceShare) -> Bool

    TraceShare::not_equal

    fn TraceShare::not_equal(x : TraceShare, y : TraceShare) -> Bool

    TraceWriter

    pub struct TraceWriter[D, T, R] {
    // private fields
    }

    A writer seals contiguous intervals; compaction is governed by all live readers.

    TraceWriter::close

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] TraceWriter::close(self : TraceWriter[D, T, R]) -> Unit

    TraceWriter::exert

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] TraceWriter::exert(self : TraceWriter[D, T, R]) -> Unit

    Request background merging. Eager traces have already performed this work.

    TraceWriter::insert

    fn[D : Compare + Eq, T : Lattice + Compare + Eq, R : Semigroup] TraceWriter::insert(self : TraceWriter[D, T, R], batch : Batch[D, T, R]) -> Unit

    TraceWriter::set_exert_logic

    fn[D, T, R] TraceWriter::set_exert_logic(self : TraceWriter[D, T, R], logic : (Array[(Int, Int, Int)]) -> Int?) -> Unit

    Configure fueled maintenance. This is only supported by shared_spine traces.

    TraceWriter::upper

    fn[D, T : Lattice + Compare + Eq, R] TraceWriter::upper(self : TraceWriter[D, T, R]) -> Antichain[T]

    UInt128

    pub struct UInt128 {
    // private fields
    } derive(Compare, Eq, Hash,
    Debug
    )

    Fixed-width unsigned 128-bit integer. Difference arithmetic wraps modulo 2^128; timestamp summary arithmetic detects overflow. Storage uses core BigInt.
    impl Lattice for UInt128
    impl Monoid for UInt128
    impl RustHash for UInt128

    UInt128::UInt128

    fn UInt128::UInt128(value : UInt64) -> UInt128

    UInt128::checked_add

    fn UInt128::checked_add(self : UInt128, other : UInt128) -> UInt128?

    UInt128::compare

    fn UInt128::compare(UInt128, UInt128) -> Int

    UInt128::equal

    fn UInt128::equal(UInt128, UInt128) -> Bool

    UInt128::from_words

    fn UInt128::from_words(high : UInt64, low : UInt64) -> UInt128

    UInt128::hash

    fn UInt128::hash(self : UInt128) -> Int

    UInt128::hash_combine

    fn UInt128::hash_combine(UInt128, Hasher) -> Unit

    UInt128::hash_into

    fn UInt128::hash_into(self : UInt128, hasher : FnvHasher) -> Unit

    UInt128::is_zero

    fn UInt128::is_zero(self : UInt128) -> Bool

    UInt128::join

    fn UInt128::join(self : UInt128, other : UInt128) -> UInt128

    UInt128::less_equal

    fn UInt128::less_equal(self : UInt128, other : UInt128) -> Bool

    UInt128::meet

    fn UInt128::meet(self : UInt128, other : UInt128) -> UInt128

    UInt128::minimum

    fn UInt128::minimum() -> UInt128

    UInt128::multiply

    fn UInt128::multiply(self : UInt128, other : UInt128) -> UInt128

    UInt128::not_equal

    fn UInt128::not_equal(x : UInt128, y : UInt128) -> Bool

    UInt128::op_ge

    fn UInt128::op_ge(x : UInt128, y : UInt128) -> Bool

    UInt128::op_gt

    fn UInt128::op_gt(x : UInt128, y : UInt128) -> Bool

    UInt128::op_le

    fn UInt128::op_le(x : UInt128, y : UInt128) -> Bool

    UInt128::op_lt

    fn UInt128::op_lt(x : UInt128, y : UInt128) -> Bool

    UInt128::plus

    fn UInt128::plus(self : UInt128, other : UInt128) -> UInt128

    UInt128::to_repr

    UInt128::to_string

    fn UInt128::to_string(self : UInt128) -> String

    UInt128::to_words

    fn UInt128::to_words(self : UInt128) -> (UInt64, UInt64)

    UInt128::try_from_bigint

    fn UInt128::try_from_bigint(value :
    BigInt
    ) -> UInt128?

    UInt128::zero

    fn UInt128::zero() -> UInt128

    UpdatesBuilder

    pub struct UpdatesBuilder[K, V, T, R] {
    // private fields
    }

    Ordered builder. Melded chunks must be consolidated and strictly increasing in (key, value, time); key/value groups can continue across chunk boundaries.

    UpdatesBuilder::UpdatesBuilder

    fn[K, V, T, R] UpdatesBuilder::UpdatesBuilder() -> UpdatesBuilder[K, V, T, R]

    UpdatesBuilder::done

    fn[K, V, T, R] UpdatesBuilder::done(self : UpdatesBuilder[K, V, T, R]) -> UpdatesTyped[K, V, T, R]

    UpdatesBuilder::meld

    fn[K : Compare + Eq, V : Compare + Eq, T : Compare + Eq, R : Semigroup] UpdatesBuilder::meld(self : UpdatesBuilder[K, V, T, R], chunk : UpdatesTyped[K, V, T, R]) -> Unit

    UpdatesBuilder::push

    fn[K : Compare + Eq, V : Compare + Eq, T : Compare + Eq, R : Semigroup] UpdatesBuilder::push(self : UpdatesBuilder[K, V, T, R], row : (K, V, T, R)) -> Unit

    UpdatesTyped

    pub struct UpdatesTyped[K, V, T, R] {
    // private fields
    }

    Four-level key/value/time/difference trie. Leaves may be unconsolidated, including repeated keys, times, and several differences at one time.

    UpdatesTyped::UpdatesTyped

    fn[K, V, T, R] UpdatesTyped::UpdatesTyped(rows : Array[(K, V, T, R)]) -> UpdatesTyped[K, V, T, R]

    Build singleton groups from raw updates without sorting or consolidation.

    UpdatesTyped::batch

    fn[K : Eq, V : Eq, T : Lattice + Compare + Eq, R] UpdatesTyped::batch(self : UpdatesTyped[K, V, T, R], description : Description[T]) -> Batch[(K, V), T, R]

    Store a consolidated update trie as a regular immutable indexed batch without flattening records. The standard trace, spill, import and cursor APIs apply.

    UpdatesTyped::columns

    fn[K, V, T, R] UpdatesTyped::columns(self : UpdatesTyped[K, V, T, R]) -> (ColumnLists[K], ColumnLists[V], ColumnLists[T], ColumnLists[R])

    UpdatesTyped::consolidate

    fn[K : Compare + Eq, V : Compare + Eq, T : Compare + Eq, R : Semigroup] UpdatesTyped::consolidate(self : UpdatesTyped[K, V, T, R]) -> UpdatesTyped[K, V, T, R]

    UpdatesTyped::extract

    fn[K, V, T : Lattice + Compare + Eq, R] UpdatesTyped::extract(self : UpdatesTyped[K, V, T, R], upper : Antichain[T]) -> (UpdatesTyped[K, V, T, R], UpdatesTyped[K, V, T, R], Antichain[T])

    Partition a consolidated chunk by an arbitrary partial-order frontier. Ready times are those not at-or-after any upper-frontier element.

    UpdatesTyped::filter_zero

    fn[K, V, T, R] UpdatesTyped::filter_zero(self : UpdatesTyped[K, V, T, R]) -> UpdatesTyped[K, V, T, R]

    Remove empty difference lists and their newly empty ancestors. As upstream, this assumes at most one difference per time and does not test numeric zeros.

    UpdatesTyped::form

    fn[K : Compare + Eq, V : Compare + Eq, T : Compare + Eq, R : Semigroup] UpdatesTyped::form(rows : Iter[(K, V, T, R)]) -> UpdatesTyped[K, V, T, R]

    Consolidate a sorted stream without materializing an intermediate row array.

    UpdatesTyped::form_unsorted

    fn[K : Compare + Eq, V : Compare + Eq, T : Compare + Eq, R : Semigroup] UpdatesTyped::form_unsorted(rows : Iter[(K, V, T, R)]) -> UpdatesTyped[K, V, T, R]

    UpdatesTyped::from_columns

    fn[K, V, T, R] UpdatesTyped::from_columns(keys : ColumnLists[K], vals : ColumnLists[V], times : ColumnLists[T], diffs : ColumnLists[R]) -> UpdatesTyped[K, V, T, R]

    Adapt four independently stored list columns. Each parent value must have exactly one child list; empty child lists are allowed.

    UpdatesTyped::is_empty

    fn[K, V, T, R] UpdatesTyped::is_empty(self : UpdatesTyped[K, V, T, R]) -> Bool

    UpdatesTyped::iter

    fn[K, V, T, R] UpdatesTyped::iter(self : UpdatesTyped[K, V, T, R]) -> Iter[(K, V, T, R)]

    Stream leaves in storage order. Empty groups at every level are skipped.

    UpdatesTyped::length

    fn[K, V, T, R] UpdatesTyped::length(self : UpdatesTyped[K, V, T, R]) -> Int

    UpdatesTyped::merge_pair

    fn[K : Compare + Eq, V : Compare + Eq, T : Compare + Eq, R : Semigroup] UpdatesTyped::merge_pair(self : UpdatesTyped[K, V, T, R], other : UpdatesTyped[K, V, T, R]) -> (UpdatesTyped[K, V, T, R], UpdatesTyped[K, V, T, R]?, UpdatesTyped[K, V, T, R]?)

    Merge one input completely and the corresponding prefix of the other. At most one returned suffix is nonempty. Cancellations are removed immediately (equivalent to upstream merge_pair followed by filter_zero).

    UpdatesTyped::split_at

    fn[K, V, T, R] UpdatesTyped::split_at(self : UpdatesTyped[K, V, T, R], count : Int) -> (UpdatesTyped[K, V, T, R], UpdatesTyped[K, V, T, R])

    Split at a leaf count, preserving column grouping on either side. A split beyond the end returns the entire chunk and an empty suffix.

    UpdatesTyped::suffix_chunk

    fn[K, V, T, R] UpdatesTyped::suffix_chunk(self : UpdatesTyped[K, V, T, R], cursor : (Int, Int, Int)) -> UpdatesTyped[K, V, T, R]

    Copy the suffix starting at flat key/value/time column indices.

    UpdatesTyped::times_bounds

    fn[K, V, T, R] UpdatesTyped::times_bounds(self : UpdatesTyped[K, V, T, R], lower : Int, upper : Int) -> (Int, Int)

    UpdatesTyped::vals_bounds

    fn[K, V, T, R] UpdatesTyped::vals_bounds(self : UpdatesTyped[K, V, T, R], lower : Int, upper : Int) -> (Int, Int)

    Variable

    pub struct Variable[D, T, R, S] {
    // private fields
    }

    A differential fixed-point variable. Set its definition once before execution.

    Variable::set

    fn[D, T : Lattice + Compare + Eq, R, S] Variable::set(self : Variable[D, T, R, S], definition : Collection[D, T, R]) -> Unit

    Feed the definition back once. Variables created with variable_from carry a pre-negated initial source, so those records are not reinjected. Empty variables require no subtraction and support semigroup-only differences.

    VectorDiff

    pub struct VectorDiff[R] {
    // private fields
    } derive(Compare, Eq,
    Debug
    )

    Immutable vector difference. Addition keeps the longer vector, treating missing suffix entries as identities. Trailing zeros need not have a canonical length.
    impl Abelian for VectorDiff[R]
    impl Monoid for VectorDiff[R]
    impl Semigroup for VectorDiff[R]

    VectorDiff::VectorDiff

    fn[R] VectorDiff::VectorDiff(values : Array[R]) -> VectorDiff[R]

    VectorDiff::compare

    fn[R : Compare + Eq] VectorDiff::compare(VectorDiff[R], VectorDiff[R]) -> Int

    VectorDiff::equal

    fn[R : Eq] VectorDiff::equal(VectorDiff[R], VectorDiff[R]) -> Bool

    VectorDiff::is_zero

    fn[R : Semigroup] VectorDiff::is_zero(self : VectorDiff[R]) -> Bool

    VectorDiff::negate

    fn[R : Abelian + Monoid + Semigroup] VectorDiff::negate(self : VectorDiff[R]) -> VectorDiff[R]

    VectorDiff::not_equal

    fn[R : Eq] VectorDiff::not_equal(x : VectorDiff[R], y : VectorDiff[R]) -> Bool

    VectorDiff::op_ge

    fn[R : Compare + Eq] VectorDiff::op_ge(x : VectorDiff[R], y : VectorDiff[R]) -> Bool

    VectorDiff::op_gt

    fn[R : Compare + Eq] VectorDiff::op_gt(x : VectorDiff[R], y : VectorDiff[R]) -> Bool

    VectorDiff::op_le

    fn[R : Compare + Eq] VectorDiff::op_le(x : VectorDiff[R], y : VectorDiff[R]) -> Bool

    VectorDiff::op_lt

    fn[R : Compare + Eq] VectorDiff::op_lt(x : VectorDiff[R], y : VectorDiff[R]) -> Bool

    VectorDiff::plus

    fn[R : Semigroup] VectorDiff::plus(self : VectorDiff[R], other : VectorDiff[R]) -> VectorDiff[R]

    VectorDiff::scale

    fn[R, S, T] VectorDiff::scale(self : VectorDiff[R], scalar : S, multiply : (R, S) -> T) -> VectorDiff[T]

    VectorDiff::to_array

    fn[R] VectorDiff::to_array(self : VectorDiff[R]) -> Array[R]

    VectorDiff::zero

    fn[R : Monoid + Semigroup] VectorDiff::zero() -> VectorDiff[R]

    WireCodec

    pub struct WireCodec[T] {
    // private fields
    }

    Explicit codecs make distributed data and timestamp serialization independent of the execution backend. Decode must reject malformed values.

    WireCodec::WireCodec

    fn[T] WireCodec::WireCodec(encode~ : (T) -> Json, decode~ : (Json) -> T?) -> WireCodec[T]

    WireCodec::from_json

    fn[T] WireCodec::from_json(self : WireCodec[T], value : Json) -> T?

    WireCodec::json

    Core JSON encoding preserves 64-bit integers as decimal strings.

    WireCodec::pointstamp

    fn[T : Timestamp + Lattice + Compare + Eq] WireCodec::pointstamp(scalar : WireCodec[T]) -> WireCodec[PointStamp[T]]

    Encode runtime timestamp coordinates using an explicit scalar codec.

    WireCodec::pointstamp_summary

    fn[S] WireCodec::pointstamp_summary(scalar : WireCodec[S]) -> WireCodec[PointStampSummary[S]]

    Encode truncation and coordinate actions for distributed dynamic scopes.

    WireCodec::product

    fn[A, B] WireCodec::product(a : WireCodec[A], b : WireCodec[B]) -> WireCodec[Product[A, B]]

    WireCodec::to_json

    fn[T] WireCodec::to_json(self : WireCodec[T], value : T) -> Json

    Worker

    pub struct Worker {
    // private fields
    }

    Cooperative worker. Each scope is frozen on first execution or input flush; fresh scopes can be built between worker steps.

    Worker::Worker

    fn Worker::Worker(clock? : () -> Duration) -> Worker

    Worker::differential_logs

    fn Worker::differential_logs(self : Worker) -> LogRegistry[DifferentialEvent]

    Register differential events under "differential/arrange" before building arrangements. Existing operators retain the logger captured at construction.

    Worker::dispose

    fn Worker::dispose(self : Worker) -> Unit

    Worker::drop_dataflow

    fn Worker::drop_dataflow(self : Worker, id : Int) -> Unit

    Cancel a local root dataflow and every nested scope. Pending records are discarded; other dataflows and independently owned trace readers survive. Cancelled probes retain their last observed frontier, as in Timely. Unknown or already completed identities are harmless. Coordinated dataflows must be cancelled through their group or cluster, never one peer alone.

    Worker::has_dataflows

    fn Worker::has_dataflows(self : Worker) -> Bool

    Worker::input

    fn[D, T : Lattice + Compare + Eq, R] Worker::input(self : Worker, initial : T) -> (InputSession[D, T, R], Collection[D, T, R])

    Worker::installed_dataflows

    fn Worker::installed_dataflows(self : Worker) -> Array[Int]

    Currently installed root scopes, in creation order.

    Worker::next_activation

    fn Worker::next_activation(self : Worker) -> Duration?

    Time until runnable work or the earliest timer; None means no queued wakeup. A nonempty capability frontier alone does not imply a queued activation.

    Worker::next_dataflow_index

    fn Worker::next_dataflow_index(self : Worker) -> Int

    The next root scope's identity. Nested scopes share their root's identity.

    Worker::run

    fn Worker::run(self : Worker, max_steps? : Int) -> RunResult

    Worker::scope

    fn[T : Lattice + Compare + Eq, S : Compare + Eq] Worker::scope(self : Worker, minimum : T, domain : SummaryDomain[T, S]) -> Scope[T, S]

    Worker::step

    fn Worker::step(self : Worker) -> Bool

    Execute one activated operator; true means a task ran, not that inputs are complete.

    WorkerGroup

    pub struct WorkerGroup {
    // private fields
    }

    Cooperative workers sharing memory. Exchange is data parallel; execution is single-threaded. Network transport and cross-process progress are separate work.

    WorkerGroup::WorkerGroup

    fn WorkerGroup::WorkerGroup(peers : Int, clock? : () -> Duration) -> WorkerGroup

    WorkerGroup::dispose

    fn WorkerGroup::dispose(self : WorkerGroup) -> Unit

    WorkerGroup::drop_dataflow

    fn WorkerGroup::drop_dataflow(self : WorkerGroup, id : Int) -> Unit

    Cancel corresponding root dataflows on every cooperative worker. IDs for group-built root scopes match across peers; nested scopes share that ID.

    WorkerGroup::next_activation

    fn WorkerGroup::next_activation(self : WorkerGroup) -> Duration?

    WorkerGroup::peers

    fn WorkerGroup::peers(self : WorkerGroup) -> Int

    WorkerGroup::run

    fn WorkerGroup::run(self : WorkerGroup, max_steps? : Int) -> RunResult

    WorkerGroup::scopes

    fn[T : Lattice + Compare + Eq, S : Compare + Eq] WorkerGroup::scopes(self : WorkerGroup, minimum : T, domain : SummaryDomain[T, S]) -> ScopeGroup[T, S]

    WorkerGroup::step

    fn WorkerGroup::step(self : WorkerGroup) -> Bool

    WorkerGroup::worker

    fn WorkerGroup::worker(self : WorkerGroup, index : Int) -> Worker

    Wrapping

    pub struct Wrapping[R] {
    // private fields
    } derive(Compare, Eq, Hash,
    Debug
    )

    Explicit wrapping signed difference adapter. MoonBit integer difference arithmetic already wraps on every backend; this preserves that behavior while giving translated Rust Wrapping programs a distinct public type.
    impl Abelian for Wrapping[R]
    impl Monoid for Wrapping[R]
    impl Ring for Wrapping[R]
    impl Semigroup for Wrapping[R]

    Wrapping::Wrapping

    fn[R] Wrapping::Wrapping(value : R) -> Wrapping[R]

    Wrapping::compare

    fn[R : Compare + Eq] Wrapping::compare(Wrapping[R], Wrapping[R]) -> Int

    Wrapping::equal

    fn[R : Eq] Wrapping::equal(Wrapping[R], Wrapping[R]) -> Bool

    Wrapping::hash

    fn[R : Hash] Wrapping::hash(self : Wrapping[R]) -> Int

    Wrapping::hash_combine

    fn[R : Hash] Wrapping::hash_combine(Wrapping[R], Hasher) -> Unit

    Wrapping::is_zero

    fn[R : Semigroup] Wrapping::is_zero(self : Wrapping[R]) -> Bool

    Wrapping::multiply

    fn[R : Ring + Abelian + Monoid + Semigroup] Wrapping::multiply(self : Wrapping[R], other : Wrapping[R]) -> Wrapping[R]

    Wrapping::negate

    fn[R : Abelian + Monoid + Semigroup] Wrapping::negate(self : Wrapping[R]) -> Wrapping[R]

    Wrapping::not_equal

    fn[R : Eq] Wrapping::not_equal(x : Wrapping[R], y : Wrapping[R]) -> Bool

    Wrapping::one

    fn[R : Ring + Abelian + Monoid + Semigroup] Wrapping::one() -> Wrapping[R]

    Wrapping::op_ge

    fn[R : Compare + Eq] Wrapping::op_ge(x : Wrapping[R], y : Wrapping[R]) -> Bool

    Wrapping::op_gt

    fn[R : Compare + Eq] Wrapping::op_gt(x : Wrapping[R], y : Wrapping[R]) -> Bool

    Wrapping::op_le

    fn[R : Compare + Eq] Wrapping::op_le(x : Wrapping[R], y : Wrapping[R]) -> Bool

    Wrapping::op_lt

    fn[R : Compare + Eq] Wrapping::op_lt(x : Wrapping[R], y : Wrapping[R]) -> Bool

    Wrapping::plus

    fn[R : Semigroup] Wrapping::plus(self : Wrapping[R], other : Wrapping[R]) -> Wrapping[R]

    Wrapping::value

    fn[R] Wrapping::value(self : Wrapping[R]) -> R

    Wrapping::zero

    fn[R : Monoid + Semigroup] Wrapping::zero() -> Wrapping[R]

    advance_by

    fn[T : Lattice + Compare + Eq] advance_by(time : T, frontier : Antichain[T]) -> T

    Upstream lattice compaction: meet of joins with frontier elements.

    consolidate

    fn[D : Compare + Eq, R : Semigroup] consolidate(input : Array[(D, R)]) -> Array[(D, R)]

    Sorted, nonzero sums of weights for each equal key; input array is unchanged.

    consolidate_updates

    fn[D : Compare + Eq, T : Compare + Eq, R : Semigroup] consolidate_updates(input : Array[(D, T, R)]) -> Array[(D, T, R)]

    Consolidates by record and timestamp, retaining incomparable times separately.

    extract_update_chunks

    fn[K, V, T : Lattice + Compare + Eq, R] extract_update_chunks(chunks : Iter[UpdatesTyped[K, V, T, R]], upper : Antichain[T], frontier : Antichain[T], ship~ : (UpdatesTyped[K, V, T, R]) -> Unit, kept~ : (UpdatesTyped[K, V, T, R]) -> Unit) -> Unit

    Lazily extract an input sequence, delivering each partition immediately to caller-owned sinks. The supplied frontier accumulates all retained times.

    rust_hash

    fn[T : RustHash] rust_hash(value : T) -> UInt64

    scale_pair

    fn[A, B, S, X, Y] scale_pair(values : (A, B), scalar : S, first~ : (A, S) -> X, second~ : (B, S) -> Y) -> (X, Y)

    Tuple multiplication with independently typed results. Explicit callbacks adapt Rust Multiply's associated Output type without restricting it to Self.

    scale_quad

    fn[A, B, C, D, S, X, Y, Z, W] scale_quad(values : (A, B, C, D), scalar : S, first~ : (A, S) -> X, second~ : (B, S) -> Y, third~ : (C, S) -> Z, fourth~ : (D, S) -> W) -> (X, Y, Z, W)

    scale_triple

    fn[A, B, C, S, X, Y, Z] scale_triple(values : (A, B, C), scalar : S, first~ : (A, S) -> X, second~ : (B, S) -> Y, third~ : (C, S) -> Z) -> (X, Y, Z)

    scale_unit

    fn[S] scale_unit(_value : Unit, _scalar : S) -> Unit

    shared_spine

    fn[D, T : Lattice + Compare + Eq, R] shared_spine(minimum : T, logger? : TraceLogger) -> (TraceWriter[D, T, R], TraceAgent[D, T, R])

    Shared trace with a fueled spine backend and independently pinned readers.

    shared_trace

    fn[D, T : Lattice + Compare + Eq, R] shared_trace(minimum : T, logger? : TraceLogger) -> (TraceWriter[D, T, R], TraceAgent[D, T, R])