fix(store): rustdoc hygiene + u64-safe cursor clamping

- resolve or unlink 25 preexisting rustdoc warnings: broken
  intra-doc links (error variants), public-docs-linking-private-items
  (crate-internal cursor/registry names), and one stale reference to a
  `Store::window_host` that never existed (the form branch is
  `sweep_window`'s engine-enum match)
- `clamped` runs its arithmetic in u64 and narrows to usize after
  clamping, so a wide u64 offset can never wrap onto a small slice
  position on narrow-pointer targets; the cursor contract tests pin
  the overflowing-offset and overflowing-length forms
- zero rustdoc warnings under RUSTDOCFLAGS=-D warnings

Verification: cargo test (69+19+3 green), cargo test --all-features
(124+54+4 green), cargo clippy --all-targets -- -D warnings green,
cargo fmt --check green, RUSTDOCFLAGS=-D warnings cargo doc --no-deps
green.
This commit is contained in:
glm-5.3-flash committed 2026-10-12 05:40:09 +00:00
1 parent 97cdf682c4
commit 611d30a3c4
6 files changed
+47 -28

No files matched your search

+19 -3
View File
@@ -242,10 +242,16 @@ pub(crate) trait Backend: Send + Sync {
/// EOF-clamping arithmetic of the cursor contract. Crate-internal: the
/// engine cursor bodies behind [`Backend::Cursor`] compose this, so every
/// engine's materializing and staging bodies clamp identically.
///
/// The arithmetic runs in `u64` — the offset/len domain — and narrows to
/// `usize` only after clamping, so a truncated `as usize` cast can never
/// wrap a huge offset back onto a small slice position on narrow-pointer
/// targets.
pub(crate) fn clamped(offset: u64, len: u64, total: usize) -> (usize, usize) {
let start = (offset as usize).min(total);
let end = start.saturating_add(len as usize).min(total);
(start, end)
let total = total as u64;
let start = offset.min(total);
let end = start.saturating_add(len).min(total);
(start as usize, end as usize)
}
#[cfg(test)]
@@ -333,6 +339,16 @@ mod tests {
Vec::<u8>::new(),
"read at EOF is empty, never an error"
);
assert_eq!(
cursor.read_at(u64::MAX, 5).await.unwrap(),
Vec::<u8>::new(),
"an overflowing u64 offset clamps to EOF in u64 arithmetic — never wraps"
);
assert_eq!(
cursor.read_at(0, u64::MAX).await.unwrap(),
whole,
"an overflowing u64 length clamps to the whole body"
);
assert_eq!(
cursor.read_at(0, 0).await.unwrap(),
Vec::<u8>::new(),
+1 -1
View File
@@ -1,7 +1,7 @@
//! Size-threshold dispatch between the kv and large tiers (ADR-003):
//! routing as a pure function of content length.
//!
//! **The routing seam the facade programs through.** [`route`] is the
//! **The routing seam the facade programs through.** `route` is the
//! pure function — `route(len, threshold) → Tier`, **at-or-below the
//! threshold stays on the kv tier** (the boundary's pinned reading:
//! store-put-paths' "≤ threshold → kv; > threshold → large") — and
+5 -4
View File
@@ -3,11 +3,12 @@
//! **One enum, both altitudes.** This is a *single* enum serving both
//! altitudes of the crate's surface. The [`Backend`][crate::backend]
//! trait's methods return this family but its *effective* members are
//! [`Missing`], [`Verification`], [`Io`], and [`KeyInvalid`] — at the
//! trait boundary, keys arrive opaque (so `KeyInvalid` never fires
//! `Error::Missing`, `Error::Verification`, `Error::Io`, and
//! `Error::KeyInvalid` — at the
//! trait boundary, keys arrive opaque (so `Error::KeyInvalid` never fires
//! there) and GC delete-arbitration answers flow up as data, not as
//! errors (so `GcRefuse` never fires below the facade). The facade's
//! public surface re-exposes this same family with [`GcRefuse`] added:
//! errors (so `Error::GcRefuse` never fires below the facade). The facade's
//! public surface re-exposes this same family with `Error::GcRefuse` added:
//! the facade decides and owns the refusal. The altitude discipline is
//! carried by doc comments and construction discipline, not by two
//! separate types (named design point audited at the review gate;
+6 -5
View File
@@ -17,7 +17,7 @@
//! (`Error::Io` naming the path): a malformed list is as deadly as an
//! incomplete one (ADR-003), and it is silent until a sweep deletes
//! the wrong things. Only the engine's own staging directory
//! ([`staging_dir`], excluded from the walk) is a known non-shard
//! (`staging_dir`, excluded from the walk) is a known non-shard
//! entry.
//!
//! **Concurrency posture:** every file operation — constructor,
@@ -32,9 +32,10 @@
//! **Stage hygiene (store-api.md invariant 3):** publish is the
//! commit-rename; every failure path converges on discard with zero
//! residue — a failed commit removes the stage file itself (there is
//! no post-failure discard to drive), an explicit [`StagingCursor::discard`]
//! removes it, and a staging cursor dropped without either is
//! best-effort-cleaned by [`Drop`] (the engine's own cancellation
//! no post-failure discard to drive), an explicit
//! `StagingCursor::discard` removes it, and a staging cursor dropped
//! without either is best-effort-cleaned by [`Drop`] (the engine's own
//! cancellation
//! story, per the wave-1 review's recorded observation; the hygiene
//! tests below cover all three forms exactly). CAS is first-writer-wins
//! everywhere a publish meets an existing entry: the committed file for
@@ -43,7 +44,7 @@
//!
//! The `#![allow(dead_code)]` below marks the narrow remaining scope:
//! in default builds (no `mem`) nothing constructs the engine, so
//! [`LocalBackend::new`]/the staged-put bodies have no caller until
//! `LocalBackend::new`/the staged-put bodies have no caller until
//! wave 3's facade constructors and `store-put-paths` name them.
#![allow(dead_code)]
+1 -1
View File
@@ -7,7 +7,7 @@
//!
//! **Schema (POC #5 finding B5's row shape adapted to sqlite):**
//! `blobs (key BLOB PRIMARY KEY, value BLOB, size INTEGER NOT NULL)`.
//! The dedicated `size` column is what makes [`Backend::size`]
//! The dedicated `size` column is what makes `Backend::size`
//! metadata-only — `SELECT size … WHERE key = ?` rides the key's index
//! and never loads the value blob (ADR-008's size discipline;
//! plan-tested below). `has` is an EXISTS probe, never a value load.
+15 -14
View File
@@ -19,8 +19,8 @@
//! would leak engine types through the public surface, force consumers
//! to name engines they must never see (the facade is **engine-blind**,
//! ADR-007/008/010), or push `dyn` onto the surface. The concrete type
//! holds two crate-internal engine-holding enums ([`KvEngine`],
//! [`LargeEngine`]) dispatching over the closed five-engine set; the
//! holds two crate-internal engine-holding enums (`KvEngine`,
//! `LargeEngine`) dispatching over the closed five-engine set; the
//! conformance factory's binding note anticipated exactly this collapse
//! (tests/conformance/factory.rs — "most plausibly the associated type
//! collapsing to the concrete facade type across all factories"). The
@@ -34,7 +34,7 @@
//! **Constructor modes** (ADR-011 §4; ADR-012 §6.3):
//!
//! - **dual-tier** (the default): kv + large, size-threshold dispatch
//! via [`crate::dispatch::route`]. The wave-2 constructible shape is
//! via `crate::dispatch::route`. The wave-2 constructible shape is
//! `kv = mem` + `large = local` — the dispatch-coverage test shape
//! ADR-012 §6.3 names (both tiers load-bearing); the wave-3
//! constructible shape is `kv = sqlite` + `large = local` — the
@@ -61,9 +61,9 @@
//! **Read-path design points (recorded for the review gate):**
//!
//! - **The fall-through general rule (ADR-012 §6.1; POC #1 finding
//! 6).** Every key-addressed op consults [`KvEngine`] first, then
//! [`LargeEngine`] — there is no length routing on the read side and
//! [`Store::tier_for`] is never consulted by it (the dispatch seam's
//! 6).** Every key-addressed op consults `KvEngine` first, then
//! `LargeEngine` — there is no length routing on the read side and
//! `Store::tier_for` is never consulted by it (the dispatch seam's
//! write-half routing is the put path's; `route` feeds nothing on
//! reads). A miss on both tiers resolves per op's shape: `Ok(None)`
//! on get/stat, `false` on has, `Err(Missing)` on read_range.
@@ -71,14 +71,14 @@
//! returns the pinned `(len, stream)` shape as
//! `Option<(u64, Blob)>` (store-api.md §Read path) — [`Blob`] is a
//! bounded, re-entrant windowed reader over the crate-internal
//! [`AnyCursor`], which dispatches the engine cursor bodies by tier
//! `AnyCursor`, which dispatches the engine cursor bodies by tier
//! (mem's materializing body for kv, `local`'s pread body for
//! large). Windowed reads are the uniform stream shape across
//! tiers; no chunk-iterator machinery was adopted — the cursor
//! bodies *are* the streaming abstraction, and per-chunk `Stream`-
//! wrapping would re-shape them without changing the underlying
//! reads. Engine cursors never leak onto the public surface:
//! [`AnyCursor`] is `pub(crate)`, `Blob` is opaque but drivable
//! `AnyCursor` is `pub(crate)`, `Blob` is opaque but drivable
//! (constructed only by the store core, ADR-010 §1).
//! - **Verification-on-get (named design point, pinned against
//! ADR-006's text).** The whole-blob hash-check fires where the
@@ -190,11 +190,12 @@
//! machinery.
//!
//! **The dispatch seam the ops tasks program through:** tier selection
//! for a given length ([`Store::tier_for`] composing
//! [`crate::dispatch::route`] per mode), the fall-through consult
//! for a given length (`Store::tier_for` composing
//! `crate::dispatch::route` per mode), the fall-through consult
//! order — **kv first, then large** — that every key-addressed op
//! consumes (ADR-012 §6.1's general rule; [`Store::kv`] then
//! [`Store::large`]), and the GC state home ([`crate::gc::GcHome`])
//! consumes (ADR-012 §6.1's general rule; `Store::kv` then
//! `Store::large`), and the GC state home (`GcHome`,
//! crate-internal)
//! the gc-protocol task fills.
//!
//! **The durable delete window hosts on the kv engine when it is
@@ -208,7 +209,7 @@
//! form**, ADR-008 §2 staged re-arbitrated delete; ADR-012 §6.7 the
//! executor is the next sweep) stages its candidates on the kv engine
//! the constructor built. The form branch keys off the engine
//! representation ([`Store::window_host`] — one kv-engine-enum match
//! representation (`sweep_window`'s one kv-engine-enum match
//! arm, never a flag): the durable form runs where the host is
//! SQL-backed, the inline form verbatim on mem/local, so wave 5's
//! pg-lo dormancy (the dual-SQL instance's large-engine window clauses
@@ -275,7 +276,7 @@ pub const DEFAULT_DELETE_WINDOW_DELAY: Duration = Duration::from_secs(5 * 60);
/// Engine-blind by construction: the engines are held in crate-internal
/// enums dispatched statically (see the module's engine-representation
/// design point); consumers name modes only. The GC state home
/// ([`crate::gc::GcHome`]) rides as a field — the store instance owns
/// (`GcHome`, crate-internal) rides as a field — the store instance owns
/// all GC state (ADR-010 §2), which the gc-protocol task fills.
pub struct Store {
/// The kv-tier engine — the first consult in every fall-through.