Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions docs/design/concurrency.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,11 @@ Tracked roughly in priority order:
- [TTL design](ttl.md) — applied case for `ConcurrentExpiring<C>`
- [Cache trait hierarchy](trait-hierarchy.md) — read/mutate split and
object-safety rationale
- [Stores](../stores/README.md) — `ConcurrentStoreRead` /
`ConcurrentStore` trait family
- [Storage layer](storage.md) — `ConcurrentStoreRead` /
`ConcurrentStore` trait family rationale and the
sequential/concurrent split
- [Stores](../stores/README.md) — runtime-behaviour reference for
each concrete store
- [`src/store/traits.rs`](../../src/store/traits.rs) — concurrent
store traits
- [`src/traits.rs`](../../src/traits.rs) — `ConcurrentCache` marker
1,173 changes: 846 additions & 327 deletions docs/design/design.md

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion docs/design/metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,20 +378,23 @@ is a **separate**, simpler structure that ships unconditionally
store-layer implementation tracks:

```rust,ignore
#[non_exhaustive]
pub struct StoreMetrics {
pub hits: u64,
pub misses: u64,
pub inserts: u64,
pub updates: u64,
pub removes: u64,
pub evictions: u64,
pub expirations: u64,
}
```

The two systems coexist:

- `StoreMetrics` is the store-layer baseline. Always present, always
cheap, six counters.
cheap, seven counters. `expirations` stays at `0` on stores that
do not own a TTL surface.
- `src/metrics/` (feature-gated) is the policy-layer detailed
metrics — recorder traits, snapshots, exporter, per-policy signals.

Expand Down
11 changes: 11 additions & 0 deletions docs/design/non-goals.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,17 @@ text exporter. It does not provide:
Use your monitoring stack for those. cachekit exposes enough counters to make
policy tuning possible without making the cache own observability.

`MetricsCell` (the crate-private interior-mutability wrapper used by
`&self` recorder paths) is **not** a substitute for `AtomicU64`. It is
sound only when increments happen under exclusive external
synchronization — single-threaded, `&mut self`, or behind a write
lock / `Mutex`. A shared `RwLock::read` guard does not serialize
readers and so is not sufficient protection. Counters reachable from a
read-locked `&self` path must use `AtomicU64` (or escalate to a write
lock before recording). The contract is restated on the `unsafe impl
Sync` block in [`src/metrics/cell.rs`](../../src/metrics/cell.rs) and
in the [Metrics design](metrics.md#metricscell-interior-mutability-under-external-lock).

## Not a Policy Research Playground at the Cost of Hot Paths

New policies are welcome, but they must fit the crate's constraints:
Expand Down
447 changes: 447 additions & 0 deletions docs/design/storage.md

Large diffs are not rendered by default.

167 changes: 160 additions & 7 deletions docs/design/style-guide.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
# Documentation Style Guide

## Goals
This style guide covers two related but distinct concerns:

- **Rustdoc style** for module- and item-level documentation inside
`src/`. The audience is a Rust developer reading the API.
- **Design-doc style** for the prose docs in `docs/design/`. The
audience is a contributor (or future maintainer) trying to
understand why a piece of cachekit looks the way it does.

Both styles share the same goals: make behaviour, invariants, and
trade-offs clear without verbosity, and keep examples compile-ready
and focused.

## Rustdoc style

### Goals

- Keep module docs consistent across the codebase.
- Make behavior, invariants, and trade-offs clear without verbosity.
- Ensure examples compile and demonstrate a single, focused use case.

## Module Doc Layout
### Module doc layout

Use `//!` and follow this order:

- Architecture
- Key Components
- Core Operations
Expand All @@ -17,11 +34,14 @@ Use `//!` and follow this order:
- Thread Safety
- Implementation Notes

## Item Docstrings
Use `///` with a one-sentence summary. Mention invariants or complexity only when
they matter. Avoid Args/Returns sections unless behavior is non-obvious.
### Item docstrings

Use `///` with a one-sentence summary. Mention invariants or complexity
only when they matter. Avoid Args/Returns sections unless behavior is
non-obvious.

### Template

## Template
```rust
//! ## Architecture
//! ...
Expand Down Expand Up @@ -51,6 +71,139 @@ they matter. Avoid Args/Returns sections unless behavior is non-obvious.
//!
//! ## Implementation Notes
//! ...
///

/// Brief summary of behavior.
```

## Design-doc style

Files in `docs/design/` follow a shared shape so a reader who has
finished one knows what to expect from the next. The shape is not a
strict template — sections are added or omitted as the topic
warrants — but the meta-conventions below are uniform.

### Status preamble

Every design doc opens with a blockquote that names what the doc
covers and links its immediate siblings. The convention is
`> Status: <one-sentence framing>. Companion to <links>.`

```markdown
> Status: design rationale for the concurrent surface that ships today
> behind the `concurrency` feature flag. Companion to the cross-cutting
> principles in [`docs/design/design.md`](design.md) §3 and the trait
> rationale in [`docs/design/trait-hierarchy.md`](trait-hierarchy.md).
```

The preamble does three things in one paragraph:

- Names the doc's scope.
- States the implementation status (shipped, partially shipped, deferred).
- Anchors the doc in the wider design corpus by linking siblings.

### Section structure

- Numbered top-level sections (`§1`, `§2`, …) are encouraged when other
docs may want to cross-reference specific sections. `design.md`,
`ttl.md`, and `trait-hierarchy.md` all do this.
- Closer sections, in order, when relevant:
- **Trade-offs** — explicit tables or side-by-side prose comparing
alternatives.
- **Failure modes** — what breaks under stress, panic, contention.
- **Future directions** / **Roadmap** — what is deferred, in rough
priority order.
- **Adding a new X** — checklist for the most common contribution
pattern (new policy, new capability trait, new metric, etc.).
- **When not to use X** — explicit boundaries for users.
- **See also** — links to sibling design docs, source files, and
external references.

### Tables for trade-offs

When two or more options have different trade-offs, use a table rather
than a bulleted list. Tables make it easy to scan one column for one
property and force the writer to give every option the same set of
properties.

```markdown
| Property | Option A | Option B |
|----------|----------|----------|
| Cost | … | … |
| Memory | … | … |
```

### Diagrams

Use fenced code blocks tagged `text` for ASCII diagrams. Avoid Mermaid
or other rich diagram formats — plain text renders in every tool
(rustdoc, GitHub, terminal `less`) without configuration. See the
hierarchy diagram in `trait-hierarchy.md` for the conventional shape.

```text
┌──────────────────┐
│ Cache<K, V> │
└────────┬─────────┘
│ extends
┌────────────┼────────────┐
▼ ▼ ▼
Capability1 Capability2 Capability3
```

### Source citations

Every concrete claim that names a type, trait, or method should link
the source file. Use relative paths
(`[`src/policy/lru.rs`](../../src/policy/lru.rs)`) so the docs work
both on GitHub and in local clones. When citing a specific feature
gate, name the feature inline (`gated by `#[cfg(feature = "ttl")]`).

### Cross-references

- Refer to sibling design docs by filename, not display title:
`[concurrency](concurrency.md)` rather than `[Concurrency design](...)`.
This survives renames better and matches the rest of the corpus.
- When citing a specific section, append the section number or anchor:
`[design.md §3](design.md)`, `[concurrency.md §"Failure modes"](concurrency.md#failure-modes)`.

### Tone

- Direct, declarative prose. "The wrapper takes a write lock", not
"The wrapper will take a write lock".
- Trade-offs are stated explicitly, not buried in passive voice.
- Marketing language is out of place. "Excellent", "powerful",
"blazing fast" — replace with the property that motivated the
adjective.
- It is acceptable, and often correct, to say "this is a known sharp
edge" or "this is the wrong trait for that surface" when it is.

### `See Also` closer

Every design doc ends with a `## See Also` section. The conventional
order is:

1. **Sibling design docs** with a one-sentence framing of each link.
2. **Source files** that contain the canonical implementation.
3. **External references** (Rust API Guidelines, research papers,
Wikipedia entries) when relevant.

The framing matters: a bare list of links is less useful than a list
where each entry says why the reader might follow it.

### Adding a new design doc

Checklist:

1. **Pick a clear single topic.** If you are documenting two concerns,
split into two docs and link them.
2. **Write the status preamble first.** Naming the scope up front
keeps the rest of the doc honest.
3. **Number top-level sections** if they're likely to be
cross-referenced from elsewhere.
4. **Add a `See Also` block** to siblings that should know about the
new doc, and add a corresponding bullet to
[`docs/index.md`](../index.md).
5. **Link from `design.md`'s See Also block** so the new doc is
reachable from the index design overview.
6. **Mirror trade-offs as tables** when there are alternatives.
7. **Close with `When not to use X`** (or the equivalent) — explicit
boundaries are part of the contract.
7 changes: 5 additions & 2 deletions docs/design/trait-hierarchy.md
Original file line number Diff line number Diff line change
Expand Up @@ -411,5 +411,8 @@ GDS lands keeps the surface honest.
- [Read-only traits](../guides/read-only-traits.md) — user-facing
guidance on the `peek` / `get` split
- [`src/traits.rs`](../../src/traits.rs) — the canonical definitions
- [`src/store/traits.rs`](../../src/store/traits.rs) — parallel
trait family at the store layer (sequential + concurrent)
- [Storage layer](storage.md) — parallel trait family at the store
layer (sequential + concurrent), with the same `&V` vs. `Arc<V>`
split reasoning
- [`src/store/traits.rs`](../../src/store/traits.rs) — canonical
store-trait definitions
Loading
Loading