pub trait BaseStorageTier: Send + Sync {
// Required methods
fn name(&self) -> &str;
fn flush(&self) -> Result<(), StorageError>;
fn rollback(&self) -> Result<(), StorageError>;
fn list_by_prefix_bytes<'a>(&'a self, prefix: &str) -> ListByPrefixIter<'a>;
// Provided methods
fn debounce_ms(&self) -> Option<u32> { ... }
fn compact_every(&self) -> Option<u32> { ... }
fn compact(&self) -> Result<(), StorageError> { ... }
}Expand description
Common tier surface — cadence knobs + transaction lifecycle + bytes-level enumeration.
Implements Audit 4’s “one wave = one transaction” model:
- After every wave (and on
batch()close), Graph iterates attached tiers and callstier.flush(). - On wave-throw, Graph calls
tier.rollback()to discard pending writes. - Cross-tier atomicity is best-effort; each tier owns its own transaction.
Lock 4.D / 6.E defaults:
debounce_ms = None— sync-through flush at wave close.compact_every = None— no forced flush cap.
Required Methods§
Sourcefn name(&self) -> &str
fn name(&self) -> &str
Diagnostic tier name (e.g. "snapshot:my-graph"). Surfaces in error
messages and Display impls.
Sourcefn flush(&self) -> Result<(), StorageError>
fn flush(&self) -> Result<(), StorageError>
Commit pending writes. Graph calls at wave-close / debounce-fire.
Sourcefn rollback(&self) -> Result<(), StorageError>
fn rollback(&self) -> Result<(), StorageError>
Discard pending writes. Graph calls on wave-throw.
Sourcefn list_by_prefix_bytes<'a>(&'a self, prefix: &str) -> ListByPrefixIter<'a>
fn list_by_prefix_bytes<'a>(&'a self, prefix: &str) -> ListByPrefixIter<'a>
Lazily enumerate raw (key, bytes) pairs under a literal byte-prefix
(DS-14-storage Q5 lock).
Yields in lex-ASC key order; for the canonical WAL key format
${prefix}/${frame_seq:020}, lex-ASC string sort = numeric ASC
frame_seq sort.
Typed enumeration (decode via the tier’s codec) lives on the typed
sub-traits as free helpers — see [crate::wal::iterate_wal_frames]
(M4.E) for the WAL-aware pattern. Decoupling the enumeration from
the codec keeps this method dyn-safe (avoids a generic method on the
trait).
Backends without list support surface
StorageError::BackendNoListSupport on first iteration.
Provided Methods§
Sourcefn debounce_ms(&self) -> Option<u32>
fn debounce_ms(&self) -> Option<u32>
Debounce window in milliseconds. None (default) = sync-through.
Graph-layer attach reads this and schedules timed flush() via its
own reactive timer (M4.E); the tier itself does NOT drive a timer.
Sourcefn compact_every(&self) -> Option<u32>
fn compact_every(&self) -> Option<u32>
Force a flush every Nth accepted write regardless of debounce.
None = no cap; Some(N) triggers flush() on the Nth save (or
append_entries for log tiers).
Sourcefn compact(&self) -> Result<(), StorageError>
fn compact(&self) -> Result<(), StorageError>
Force a mode:"full" baseline immediately (Q8 lock). Bypasses
compact_every cadence; useful at deploy boundaries, end-of-process
drains, or test fixtures. Default impl is a flush() so tiers that
don’t write baselines can still implement the method trivially.