Skip to content

Bring a tier back under its bound when a pin is released - #189

Merged
matrixarkai merged 1 commit into
mainfrom
pins/a-release-leaves-the-tier-over-its-bound
Oct 24, 2026
Merged

matrixarkai merged 1 commit into
mainfrom
pins/a-release-leaves-the-tier-over-its-bound

Conversation

@matrixarkai

Copy link
Copy Markdown
Owner

A resident tier can only be above its capacity because something in it was
pinned. Every write path evicts to capacity before returning, an oversize
value is refused rather than admitted, and eviction skips a pinned entry
rather than taking it. Shrinking the capacity under a pin is how a caller gets
there: the eviction that follows takes what it can and leaves the rest.

Nothing brought it back.

a memory tier of 256 bytes, four 64-byte entries, two pinned held
after shrinking the capacity to 64 bytes 128
after releasing one handle 128
after releasing every handle 128

A cache never written to again stayed at twice its configured size for good,
and the only thing that would ever have fixed it was an unrelated write.

What changed

A release asks the question now: if any tier is over its capacity, evict to it
and drain whatever that queues, exactly as a write does. Both release paths
ask — the single handle and the batch, which counts its pins in one pass.

The common case pays three integer comparisons under the lock the release
already holds and takes no write lock: acquire and release in the allocation
report is still 0.00 allocations and 0.0 bytes.

Which entry goes is the replacement policy's business, not the release's. The
guarantee is the bound.

The companion decision, now pinned

A third test states a behaviour this change does not alter: a pinned insert
into a full tier of pinned entries hands back no handle rather than growing the
tier. The other design is defensible — let the insert through and carry the
overshoot until the handles go, so that pinning cannot fail for want of room —
and this cache keeps the bound instead, so a caller that pins a working set
larger than its capacity finds out at the pin rather than through a tier
quietly twice its configured size.

It is pinned because Ok(None) from an admission path is easy to read as
success.

Planted, as a matrix

plant single test batch test
the single release stops reclaiming fails passes
the batch release stops reclaiming passes fails

Worth stating as a matrix because the first run of those plants read as green:
the filter I passed matched three unrelated tests whose names also contain
"bound", plus one of mine the plants cannot affect, and "4 passed" looked like
the three new ones and a bystander. A panic planted inside the reclaim was what
showed the tests reach it at all.

Gates on both feature arms: cargo fmt --check, clippy --all-targets -D warnings, the suites (599 and 594), the vocabulary check, and both reports
with --require-passed.

🤖 Generated with Claude Code

A resident tier can only be above its capacity because something in it was
pinned. Every write path evicts to capacity before returning, an oversize
value is refused rather than admitted, and eviction skips a pinned entry
rather than taking it. Shrinking the capacity under a pin is how a caller
gets there: the eviction that follows takes what it can and leaves the rest.

Nothing brought it back. Measured: a memory tier of 256 bytes holding four
64-byte entries, two of them pinned, shrunk to 64 bytes -- it evicted the two
it could and held 128. Releasing one handle left 128. Releasing **every**
handle left 128. A cache never written to again stayed at twice its
configured size for good, and the only thing that would ever have fixed it
was an unrelated write.

So a release asks the question now: if any tier is over its capacity, evict to
it and drain whatever that queues, exactly as a write does. Both release paths
ask -- the single handle and the batch, which counts its pins in one pass.

The common case pays three integer comparisons under the lock the release
already holds, and takes no write lock. `acquire and release` in the
allocation report is still 0.00 allocations and 0.0 bytes.

Which entry goes is the replacement policy's business, not the release's. The
guarantee is the bound.

A third test pins the companion decision, which this change does not alter: a
pinned insert into a full tier of pinned entries hands back no handle rather
than growing the tier. The other design is defensible -- let the insert
through and carry the overshoot until the handles go, so that pinning cannot
fail for want of room -- and this one keeps the bound instead, so a caller
that pins a working set larger than the capacity finds out at the pin.

Both release paths were planted, each against both tests: removing the
reclaim from the single release fails only the single test, removing it from
the batch release fails only the batch test. Worth stating as a matrix,
because the first run of those plants read as green -- the filter I passed
matched three unrelated tests whose names also contain "bound", plus one of
mine that the plants cannot affect, and "4 passed" looked like the three new
ones and a bystander.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@matrixarkai
matrixarkai merged commit aa45545 into main Oct 24, 2026
7 checks passed
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.

2 participants