moonbitstack/moonraft/log does not have a README file

    LogCompacted

    pub suberror LogCompacted

    The one way a RaftLog read can fail: the requested index predates the snapshot baseline and has been compacted away. slice / entries / must_check_out_of_bounds narrow the storage layer's four-variant StorageError to this single mode at the boundary — a caller such as all_entries then handles exactly the failure that can occur, and no wildcard arm can silently swallow an Unavailable or contract-violating error (etcd documents that raftLog.slice only ever returns ErrCompacted).

    LogSlice

    pub(all) struct LogSlice {
    term : UInt64
    prev :
    EntryId

    entries : Array[
    Entry
    ]
    }

    A contiguous, well-formed slice of a raft log considered under a specific leader term. prev is the entry immediately before entries. Mirrors etcd's logSlice, whose invariants a well-formed append must satisfy: entries are contiguous after prev, entry terms never regress, and no entry carries a term newer than the leader term.

    LogSlice::last_entry_id

    The identity of the last entry, or prev when the slice is empty.

    LogSlice::last_index

    fn LogSlice::last_index(self : LogSlice) -> UInt64

    The index of the last entry, or prev.index when the slice is empty.

    LogSlice::valid

    fn LogSlice::valid(self : LogSlice) -> Bool

    Whether the slice is well-formed: every entry follows the previous one by exactly one index, entry terms never regress below the preceding entry, and the last entry's term does not exceed the leader term. This is the "gateway" check etcd runs on a slice sourced from a message or from storage.

    RaftLog

    pub struct RaftLog {
    storage : &
    RaftStorage

    unstable : Unstable
    committed : UInt64
    applying : UInt64
    applied : UInt64
    max_applying_ents_size : UInt64
    applying_ents_size : UInt64
    applying_ents_paused : Bool
    }

    The raft log (etcd's raftLog): a MemoryStorage of durable entries with an Unstable in-memory tail layered on top, plus the commit/apply cursors.

    committed is the highest index known committed on a quorum; applying and applied track how far the state machine has been told to apply and has finished applying. applying_ents_size / max_applying_ents_size bound the bytes of committed-but-unapplied entries handed out at once, so a burst of commits cannot force an unbounded apply batch (byte-level pagination).

    RaftLog::accept_applying

    fn RaftLog::accept_applying(self : RaftLog, i : UInt64, size : UInt64, allow_unstable : Bool) -> Unit

    Record that the application has been handed entries up to i to apply, charging size bytes against the budget and pausing when it is exhausted or when the next entry would overshoot it.

    RaftLog::accept_unstable

    fn RaftLog::accept_unstable(self : RaftLog) -> Unit

    Mark the current unstable entries and snapshot as being written.

    RaftLog::all_entries

    Every entry currently in the log.

    RaftLog::append

    fn RaftLog::append(self : RaftLog, ents : Array[
    Entry
    ]) -> UInt64

    Append ents to the unstable tail and return the new last index. Appending at or before the commit index is a corruption and aborts.

    RaftLog::applied_to

    fn RaftLog::applied_to(self : RaftLog, i : UInt64, size : UInt64) -> Unit

    Record that the state machine has finished applying up to i, releasing size bytes of the outstanding apply budget.

    RaftLog::async_stabilize

    fn RaftLog::async_stabilize(self : RaftLog, index : UInt64, log_term : UInt64) -> Unit

    Acknowledge an asynchronous append made durable up to (index, log_term): move the confirmed unstable prefix into storage and truncate the unstable tail. This is a no-op — the ABA guard — unless the unstable log still holds (index, log_term); if a later term rewrote that index, the stale ack must not be mistaken for a confirmation of the new entries.

    RaftLog::commit_stable

    fn RaftLog::commit_stable(self : RaftLog, entries : Array[
    Entry
    ]) -> Unit

    Move entries from the unstable tail into stable storage, then mark them stable — the persist half of a driver's Ready/Advance cycle.

    RaftLog::commit_to

    fn RaftLog::commit_to(self : RaftLog, tocommit : UInt64) -> Unit

    Advance the commit index (never backwards). Committing past the last index is a corruption and aborts.

    RaftLog::committed

    fn RaftLog::committed(self : RaftLog) -> UInt64

    The committed index.

    RaftLog::entries

    fn RaftLog::entries(self : RaftLog, i : UInt64, max_size : UInt64) -> Array[
    Entry
    ] raise LogCompacted

    Entries starting at i, size-capped by max_size. Empty if i is past the end; raises Compacted if i has been compacted.

    RaftLog::find_conflict

    fn RaftLog::find_conflict(self : RaftLog, ents : ArrayView[
    Entry
    ]) -> UInt64

    The index of the first entry in ents that conflicts with our log (same index, different term), or the first genuinely new index, or 0 if all match.

    RaftLog::find_conflict_by_term

    fn RaftLog::find_conflict_by_term(self : RaftLog, index : UInt64, term : UInt64) -> (UInt64, UInt64)

    A best guess at where our log stops matching another whose only known point is (index, term): the greatest i <= index with term(i) <= term, or with an unknown (compacted/unstored) term. Returns (i, term(i)-or-0).

    RaftLog::first_index

    fn RaftLog::first_index(self : RaftLog) -> UInt64

    The first index still readable (one past the snapshot).

    RaftLog::has_next_committed_ents

    fn RaftLog::has_next_committed_ents(self : RaftLog, allow_unstable : Bool) -> Bool

    Whether any committed-but-unapplied entries are ready (a light check that avoids the slice in next_committed_ents).

    RaftLog::has_next_or_in_progress_unstable_ents

    fn RaftLog::has_next_or_in_progress_unstable_ents(self : RaftLog) -> Bool

    Whether there are any unstable entries, whether or not already in progress.

    RaftLog::has_next_unstable_ents

    fn RaftLog::has_next_unstable_ents(self : RaftLog) -> Bool

    Whether any unstable entries are ready to be written.

    RaftLog::has_next_unstable_snapshot

    fn RaftLog::has_next_unstable_snapshot(self : RaftLog) -> Bool

    Whether an unstable snapshot is ready to be applied.

    RaftLog::is_up_to_date

    fn RaftLog::is_up_to_date(self : RaftLog, their :
    EntryId
    ) -> Bool

    Whether the log ending at their is at least as up-to-date as ours (§5.4.1).

    RaftLog::last_entry_id

    The identity of the last entry.

    RaftLog::last_index

    fn RaftLog::last_index(self : RaftLog) -> UInt64

    The index of the last entry in the log.

    RaftLog::match_term

    fn RaftLog::match_term(self : RaftLog, id :
    EntryId
    ) -> Bool

    Whether the log holds the identified entry with that exact term.

    RaftLog::maybe_append

    fn RaftLog::maybe_append(self : RaftLog, a : LogSlice, committed : UInt64) -> UInt64?

    Try to append the slice a after verifying its prev matches our log. On a match, splice in any genuinely new tail (a conflict with a committed entry aborts), advance commit to min(committed, last_new), and return the new last index; otherwise return None.

    RaftLog::maybe_commit

    fn RaftLog::maybe_commit(self : RaftLog, at :
    EntryId
    ) -> Bool

    The committed entries whose term matches — advance commit to at.index.

    RaftLog::must_check_out_of_bounds

    fn RaftLog::must_check_out_of_bounds(self : RaftLog, lo : UInt64, hi : UInt64) -> Unit raise LogCompacted

    Guard: first_index <= lo <= hi <= last_index + 1. Compacted when lo predates the first index; a high bound past the end aborts (etcd panics).

    RaftLog::new

    Recover a log from storage, positioned at the last compaction: committed, applying and applied all start at first_index - 1, and the unstable tail is empty just past last_index.

    RaftLog::new_with_size

    fn RaftLog::new_with_size(storage : &
    RaftStorage
    , max_applying_ents_size : UInt64) -> RaftLog

    As new, but capping the byte size of entries returned per apply batch.

    RaftLog::next_committed_ents

    fn RaftLog::next_committed_ents(self : RaftLog, allow_unstable : Bool) -> Array[
    Entry
    ]

    The committed-but-unapplied entries ready for execution, subject to the apply pause, any pending snapshot, and the byte budget. allow_unstable lets committed entries still in the unstable tail be applied.

    RaftLog::next_unstable_ents

    The unstable entries ready to be written and not already in progress.

    RaftLog::next_unstable_snapshot

    fn RaftLog::next_unstable_snapshot(self : RaftLog) ->
    Snapshot
    ?

    The unstable snapshot ready to be applied and not already in progress.

    RaftLog::pending_snapshot_index

    fn RaftLog::pending_snapshot_index(self : RaftLog) -> UInt64?

    The index of the snapshot still held in the unstable tail, if any (whether or not its write is in progress). Used to acknowledge a snapshot made durable under async storage writes, where the append response does not name it.

    RaftLog::restore

    Restore the log to a snapshot baseline: commit follows the snapshot forward, and the unstable tail is replaced by it.

    RaftLog::scan

    fn RaftLog::scan(self : RaftLog, lo : UInt64, hi : UInt64, page_size : UInt64, v : (ArrayView[
    Entry
    ]) -> Unit raise) -> Unit raise

    Visit [lo, hi) in consecutive byte-bounded pages, passing each page to v. v may raise to stop early. Each page holds at least one entry and at most page_size bytes (unless a single entry exceeds it).

    RaftLog::seed

    fn RaftLog::seed(self : RaftLog, committed : UInt64, applied : UInt64) -> Unit

    Seed the commit and applied cursors from a recovered node on construction. Commit only moves forward; applied and applying jump to the recovered point.

    RaftLog::slice

    fn RaftLog::slice(self : RaftLog, lo : UInt64, hi : UInt64, max_size : UInt64) -> Array[
    Entry
    ] raise LogCompacted

    Entries with indices in [lo, hi), size-capped by max_size, drawn from the stable storage and the unstable tail and stitched together. Compacted if lo predates the first index.

    RaftLog::snapshot

    The most recent snapshot: the unstable one if present, else storage's.

    RaftLog::stable_snap_to

    fn RaftLog::stable_snap_to(self : RaftLog, i : UInt64) -> Unit

    Confirm the unstable snapshot at index i is durably stored.

    RaftLog::stable_to

    Confirm the unstable tail entries up to id are durably stored.

    RaftLog::term

    fn RaftLog::term(self : RaftLog, i : UInt64) -> UInt64 raise
    StorageError

    The term of entry i. Compacted if it predates the first index, Unavailable if it is past the last. The term at first_index-1 is retained for log-matching even though the entry itself is gone.

    RaftLog::to_string

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

    A one-line description of the log's cursors for debugging (etcd's raftLog.String()).

    RaftLog::zero_term_on_out_of_bounds

    fn RaftLog::zero_term_on_out_of_bounds(self : RaftLog, i : UInt64) -> UInt64

    The term at i, or 0 when the index is out of bounds (etcd's zeroTermOnOutOfBounds), used where a missing term is simply "no match".

    Unstable

    pub(all) struct Unstable {
    snapshot :
    Snapshot
    ?
    entries : Array[
    Entry
    ]
    offset : UInt64
    offset_in_progress : UInt64
    snapshot_in_progress : Bool
    }

    The in-memory tail of the log that has not yet been written to Storage (etcd's unstable). It holds newly appended entries and, optionally, a snapshot waiting to be applied, until they are handed to a Ready and their writes are confirmed. entries[i] sits at absolute log index i + offset.

    offset_in_progress (exclusive, >= offset) marks how far the entries have begun being written; snapshot_in_progress says the snapshot write has begun. Following etcd, the "in progress" cursors are what let the same entries be exposed once for persistence and then withheld until stabilized. The snapshot is an Option rather than a sentinel — its absence is a real type state, not an index-0 magic value.

    Unstable::accept_in_progress

    fn Unstable::accept_in_progress(self : Unstable) -> Unit

    Mark every held entry and the snapshot as having begun their write, so they are withheld from later next_entries/next_snapshot until stabilized.

    Unstable::maybe_first_index

    fn Unstable::maybe_first_index(self : Unstable) -> UInt64?

    The first index the unstable region can speak to — one past the snapshot — or None when there is no snapshot.

    Unstable::maybe_last_index

    fn Unstable::maybe_last_index(self : Unstable) -> UInt64?

    The last index covered, if there is at least one entry or a snapshot.

    Unstable::maybe_term

    fn Unstable::maybe_term(self : Unstable, i : UInt64) -> UInt64?

    The term of the entry at i, if the unstable region knows it — either from an entry it holds or from the snapshot baseline.

    Unstable::new

    fn Unstable::new(offset : UInt64) -> Unstable

    A fresh unstable tail anchored just past the last stable entry.

    Unstable::next_entries

    The entries not already in the process of being written to storage.

    Unstable::next_snapshot

    The snapshot to write, if one is present and not already being written.

    Unstable::restore

    Replace the unstable tail with a snapshot baseline: the log restarts just past s, with no in-memory entries.

    Unstable::slice

    fn Unstable::slice(self : Unstable, lo : UInt64, hi : UInt64) -> Array[
    Entry
    ]

    The held entries with indices in [lo, hi). The whole range must lie within the unstable region, otherwise this aborts (etcd panics).

    Unstable::stable_snap_to

    fn Unstable::stable_snap_to(self : Unstable, i : UInt64) -> Unit

    Drop the snapshot once it has been written to storage.

    Unstable::stable_to

    Discard the entries up to and including id now that they are durably stored. Ignored if the entry is missing, matched only the snapshot baseline, or the term no longer matches (the unstable tail was replaced meanwhile).

    Unstable::truncate_and_append

    fn Unstable::truncate_and_append(self : Unstable, ents : Array[
    Entry
    ]) -> Unit

    Splice ents onto the tail: append directly when they follow the last held entry, replace the whole tail when they start at or before offset, or truncate the divergent suffix and append otherwise. Only in-progress entries before the truncation point stay in progress.

    describe_conf_state

    fn describe_conf_state(cs :
    ConfState
    ) -> String

    A concise description of a ConfState (etcd's DescribeConfState).

    describe_entries

    fn describe_entries(entries : ArrayView[
    Entry
    ], format : (Bytes) -> String?) -> String

    Each entry described, one per line (etcd's DescribeEntries).

    describe_entry

    fn describe_entry(e :
    Entry
    , format : (Bytes) -> String?) -> String

    A concise, human-readable description of an entry for debugging: term/index Type payload. format renders the payload; when it is None the default Go %q-style quoting is used. Mirrors etcd's DescribeEntry.

    describe_hard_state

    fn describe_hard_state(hs :
    HardState
    ) -> String

    A concise description of a HardState for debugging (etcd's DescribeHardState): Term:N [Vote:v ]Commit:N, the vote shown only when a vote was cast.

    describe_snapshot

    fn describe_snapshot(snap :
    Snapshot
    ) -> String

    A concise description of a Snapshot (etcd's DescribeSnapshot).