moonbitstack/moonraft/storage does not have a README file

    LogStore

    pub(open) trait LogStore {
    fn persist(Self, Persisted) -> Unit
    fn restore(Self) -> Persisted?
    }

    Durable storage for a node's persistent state. A real deployment backs this with a file or a database; the tests use an in-memory implementation. Keeping it a trait decouples the consensus core from any particular I/O.

    RaftStorage

    pub(open) trait RaftStorage {
    fn initial_state(Self) ->
    HardState

    fn storage_entries(Self, UInt64, UInt64, UInt64) -> Array[
    Entry
    ] raise StorageError
    fn storage_term(Self, UInt64) -> UInt64 raise StorageError
    fn first_index(Self) -> UInt64
    fn last_index(Self) -> UInt64
    fn storage_snapshot(Self) ->
    Snapshot
    raise StorageError
    fn append(Self, Array[
    Entry
    ]) -> Unit
    }

    Read access to a node's durable log, modelled on etcd's Storage interface. The consensus core reads entries, terms and the snapshot back through this trait, which lets the same core run over memory, a file or a database.

    The index/term accessors raise StorageError so a compacted index is reported distinctly from an unavailable one, exactly as etcd's Storage contract requires.

    WalStore

    pub(open) trait WalStore {
    fn append_record(Self, WalRecord) -> Unit
    fn load(Self) -> Array[WalRecord]
    }

    Durable, append-only write-ahead log. Implemented over a file in production; the in-memory MemWal in the tests is used for tests and single-process runs.

    StorageError

    pub(all) suberror StorageError {
    Compacted
    Unavailable
    SnapOutOfDate
    SnapshotTemporarilyUnavailable
    } derive(Eq)

    The failure modes a RaftStorage can report, one variant per distinguishable condition so a caller can tell "this index is gone forever" apart from "this index has not arrived yet" — a distinction etcd draws with distinct sentinel errors and one the consensus core depends on to decide between sending a snapshot and simply waiting.

    MemoryStorage

    An in-memory RaftStorage. ents[0] is a sentinel whose index and term are the snapshot baseline, so ents[i] always holds the entry at absolute index ents[0].index + i. This mirrors etcd's MemoryStorage layout, which keeps index arithmetic branch-free.

    MemoryStorage::append

    Append entries to the log, overwriting any conflicting suffix. Entries whose indices fall at or before the sentinel are already compacted and are dropped; a gap between the log and the incoming entries is a programming error and aborts, matching etcd's panic.

    MemoryStorage::apply_snapshot

    fn MemoryStorage::apply_snapshot(self : MemoryStorage, snapshot :
    Snapshot
    ) -> Unit raise StorageError

    Replace the whole log with a snapshot baseline, resetting the sentinel to the snapshot's index and term (Raft §7). A snapshot no newer than the one already stored is rejected with SnapOutOfDate.

    MemoryStorage::compact

    fn MemoryStorage::compact(self : MemoryStorage, compact_index : UInt64) -> Unit raise StorageError

    Discard every entry at or before compact_index, moving the sentinel up to that index. An index at or before the current sentinel is Compacted; one past the last entry aborts (etcd panics), since it is a caller error.

    MemoryStorage::create_snapshot

    Build a snapshot at index carrying data, remember it, and return it. An index at or before the current snapshot is SnapOutOfDate; one past the last entry aborts (etcd panics).

    MemoryStorage::from_ents

    Build storage directly over a given entry array, treating ents[0] as the compaction sentinel. Mirrors etcd's &MemoryStorage{ents: ents} test setup.

    MemoryStorage::new

    Create empty storage: an initial HardState, the empty snapshot, and a lone sentinel entry at index 0.

    MemoryStorage::raw_ents

    The raw entry array, sentinel included. Test-facing, to assert the exact post-compaction/append layout the way etcd's storage tests do.

    MemoryStorage::seed_snapshot

    fn MemoryStorage::seed_snapshot(self : MemoryStorage, snapshot :
    Snapshot
    ) -> Unit

    Install a snapshot baseline unconditionally, resetting the sentinel to its index and term. This is the write half of apply_snapshot without the out-of-date guard, for seeding a freshly created storage whose empty baseline cannot predate anything.

    MemoryStorage::set_hard_state

    Record the HardState (term, vote, commit) for the next restart.

    MemoryStorage::set_snapshot_pending

    fn MemoryStorage::set_snapshot_pending(self : MemoryStorage, pending : Bool) -> Unit

    Report the snapshot as not-yet-ready (true) or ready (false). Lets a backend signal that storage_snapshot() should be retried rather than treated as an error.

    MemoryStorage::slice

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

    A best-effort, clamping read of entries with indices in [lo, hi): indices at or before the sentinel and past the last entry are simply skipped rather than raising. Used where an approximate window is wanted without the strict etcd error contract.

    Persisted

    pub(all) struct Persisted {
    term : UInt64
    voted_for : String?
    log : Array[
    Entry
    ]
    }

    The persistent state a Raft node must save to stable storage before responding to any RPC (Raft §5.3): the current term, the vote cast in that term, and the log. It is exactly what a node reloads to recover after a crash.

    WalRecord

    One record in the write-ahead log. A real Raft node appends these to a file (fsync'd before it replies to any RPC) and replays them in order after a crash to rebuild exactly the state it had promised (Raft §5.3, §7). A WalSnapshot marks a compaction baseline; the WalEntry records after it carry the log tail; WalHardState records the term/vote/commit at the time.