Skip to content

Make the durable fold a pluggable SnapshotStore trait#2

Merged
jaredLunde merged 1 commit into
mainfrom
jared/engines
Jun 7, 2026
Merged

Make the durable fold a pluggable SnapshotStore trait#2
jaredLunde merged 1 commit into
mainfrom
jared/engines

Conversation

@jaredLunde
Copy link
Copy Markdown
Contributor

What & why

Turns the snapshot layer into a trait with swappable backends, so consumers that can't hold their fold in RAM (e.g. routing at ~1B keys) can fold to a queryable on-disk store instead. slipstream owns the durable-fold primitive; every large-bucket consumer gets it for free. The trait stops at durable fold + cursor + query — serving structures (routing rings, etc.) stay in consumers.

Changes

  • SnapshotStore trait — atomic apply(batch, cursor), load (resume), get, range. Preserves the existing invariants: pure-function-of-log, cursor-after-apply, gap-free integrity, "snapshot is a cache."
  • AppendLogSnapshot (default, pure-Rust) — the existing append-only CRC log behind the trait + an in-RAM fold for get/range. v2 on-disk format, CRC, and FDB-versionstamp-safe cursor encoding unchanged; old files still load. SnapshotWriter/load stay public and untouched.
  • FjallSnapshot (feature = "fjall") — on-disk fjall LSM backend. One atomic batch per apply commits data + cursor together; NO_SYNC configurable; cheap Slice-backed get/range. Core stays pure-Rust; the dep is feature-gated.
  • watch_applied is now generic over S: SnapshotStore — the consumer picks the backend (or None). Flush offloads store.apply to a blocking task; per-flush compaction policy moved into the backend.
  • Conformance suite (tests/snapshot_store.rs) run for each backend: the pure-fold property test (rm store mid-stream → reopen+replay → byte-identical), round-trip, cursor-resume, get/range, fjall NO_SYNC crash-tail + idempotency, and AppendLog legacy-file load.
  • README + ARCHITECTURE document the trait and backends.

⚠️ Breaking change

watch_applied's 4th arg is now Option<S: SnapshotStore> instead of Option<SnapshotWriter>. Migrate call sites to AppendLogSnapshot::open(path, threshold) (returns (cursor, store)), pass Some(store). On-disk format is unchanged, so existing snapshots keep loading. Version bumped to 0.3.0. (edge/tunnel migrations staged separately, pending the 0.3.0 publish.)

Verification

  • cargo test --lib --tests ✅ (lib 52, integration 38, snapshot_store 9)
  • cargo clippy --all-targets -- -D warnings
  • cargo test --features fjall ✅ (adds the fjall backend through the same harness)

🤖 Generated with Claude Code

Turn the snapshot layer into a trait with swappable backends so consumers
that can't hold their fold in RAM (e.g. routing at ~1B keys) can fold to a
queryable on-disk store instead. slipstream owns the durable-fold primitive;
every large-bucket consumer gets it for free.

- SnapshotStore trait: atomic apply(batch, cursor), load (resume), get, range.
  Preserves the existing invariants — pure function of the log, cursor-after-
  apply, gap-free integrity, "snapshot is a cache."
- AppendLogSnapshot (default, pure-Rust): the existing append-only CRC log,
  refactored behind the trait + an in-RAM fold for get/range. v2 on-disk format,
  CRC, and FDB-versionstamp-safe cursor encoding unchanged; old files still load.
  SnapshotWriter/load stay public and untouched.
- FjallSnapshot (feature = "fjall"): on-disk fjall LSM backend. One atomic batch
  per apply commits data + cursor together; NO_SYNC configurable; cheap
  Slice-backed get/range. Core stays pure-Rust; the C-free dep is feature-gated.
- watch_applied is now generic over S: SnapshotStore — a consumer picks the
  backend (or None). Flush offloads store.apply to a blocking task; per-flush
  compaction policy moved into the backend.
- Backend-agnostic conformance suite (tests/snapshot_store.rs) run for each
  backend: the pure-fold property test (rm store mid-stream -> reopen+replay ->
  byte-identical), round-trip, cursor-resume, get/range, fjall NO_SYNC crash-tail
  + idempotency, and AppendLog legacy-file load.
- README + ARCHITECTURE document the trait and backends.

BREAKING CHANGE: watch_applied's 4th arg is now Option<S: SnapshotStore>
instead of Option<SnapshotWriter>. Pass AppendLogSnapshot::open(path, t).1.
Bumps to 0.3.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jaredLunde jaredLunde merged commit 3ee408d into main Jun 7, 2026
1 check passed
@jaredLunde jaredLunde deleted the jared/engines branch June 7, 2026 00:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant