pub struct VersionedLfsRows<T: ?Sized> { /* private fields */ }Expand description
The LFS rows’ write counter — the LFS liveness source’s in-process
invalidation half (crate::liveness::LfsMedia’s arbitration
epoch signal): bumped on every assert through the composition’s
rows surface, read by the source’s arbitration consult. See
VersionedLfsRows.
The counter’s discipline is narrower than the refs counter’s
(crate::refs::VersionedRefTable): assert bumps, removals read
back without one. The bump covers the one dangerous direction — a
row landing
between a sweep’s mark and a staged candidate’s arbitration (the
media is newly referenced; the stale index says unreferenced; the
moved counter says unknown-is-live and cancels). A removal moves
coverage only downward — a stale “live” answer is the safe side and
a stale “dead” answer is exact for a candidate whose rows left —
and the mark’s rebuild-per-mark consult sees the truth at the next
sweep either way.
The bump follows the inner call (the epoch discipline’s
bump-after-commit half, shared with
crate::refs::VersionedRefTable): the mark consult’s counter
load rides ahead of its rows read, so only the
load-before-read / bump-after-commit pairing is sound — bump
lands strictly after the rows commit, and any write whose rows
the mark’s read missed necessarily moves the counter past the
memo’s captured epoch (the arbitration consult answers
conservatively-live). The bump-before shape was reviewed out at
the wave-9 gate: it let an assert’s bump land while its sqlite/pg
write transaction was still in flight, letting a mark’s row read
miss the uncommitted rows while catching the bump — a memo keyed
on pre-assert rows and a post-bump epoch, the poisoned shape that
answers exact-dead for just-referenced media once the commit
lands.
The twins’ record-removal legs (the in-SQL copies inside the
registry removal transactions) never touch the counter — they are
removals (coverage downward, above); the mem shape’s
LfsRows::remove_repo leg rides this surface and follows the
same discipline.
Implementations§
Source§impl<T: ?Sized> VersionedLfsRows<T>
impl<T: ?Sized> VersionedLfsRows<T>
Trait Implementations§
Source§impl<T> LfsRows for VersionedLfsRows<T>
impl<T> LfsRows for VersionedLfsRows<T>
Source§fn assert<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
repo_id: &'life1 str,
oid: &'life2 str,
size: u64,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn assert<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
repo_id: &'life1 str,
oid: &'life2 str,
size: u64,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
(repo_id, oid) row with the
asserted size, or — when the pair already has a row — refresh
that row’s size and change nothing else (the refcount-aware
upsert: one oid re-asserted in one repo is one row).Source§fn remove<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
repo_id: &'life1 str,
oid: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn remove<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
repo_id: &'life1 str,
oid: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn remove_repo<'life0, 'life1, 'async_trait>(
&'life0 self,
repo_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn remove_repo<'life0, 'life1, 'async_trait>(
&'life0 self,
repo_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn rows<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<LfsRow>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn rows<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<LfsRow>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
(repo_id, oid)
order.