Skip to content

perf(cache): prune expired entries before eviction#166

Merged
jaysin586 merged 2 commits into
mainfrom
codex/prune-before-evict
Jun 5, 2026
Merged

perf(cache): prune expired entries before eviction#166
jaysin586 merged 2 commits into
mainfrom
codex/prune-before-evict

Conversation

@jaysin586

Copy link
Copy Markdown
Contributor

Summary

Prunes expired entries before applying maxSize LRU eviction on new writes. This prevents valid LRU entries from being evicted while expired entries still occupy capacity, and documents how ttl and maxSize interact.

Closes #161.

Changes

🔧 Refactoring/improvements

  • Call prune() before LRU eviction when a new set() would hit maxSize.
  • Preserve the existing LRU eviction path when the cache is still full after pruning.

🧪 Testing

  • Add regression coverage for the case where an expired entry is more recently used than a valid LRU entry.
  • Assert expired entries are removed via prune, valid entries survive, and no size eviction is counted.

📚 Documentation

  • Update the README and MemoryCache API docs to describe prune-before-evict behavior.
  • Update the LRU examples page and examples index copy to call out TTL pruning before eviction.

Verification

  • trunk check
  • pnpm vitest run src/cache.lru.test.ts src/cache.statistics.test.ts --coverage=false
  • pnpm exec tsc --noEmit --pretty false
  • pnpm --filter docs check
  • pnpm test:only --coverage=false
  • pnpm --filter docs build
  • Browser smoke check for /examples/lru-eviction
  • CodeRabbit raised 0 issues

Commits

  • a3ee694 perf(cache): prune expired entries before eviction

Reclaim expired entries before applying maxSize LRU eviction so valid
entries are not evicted while stale entries still occupy capacity.

- Preserve LRU eviction when the cache remains full after pruning
- Add regression coverage for TTL and LRU order diverging
- Document the TTL plus maxSize behavior in README, API docs, and examples

Closes #161
@jaysin586 jaysin586 self-assigned this Jun 4, 2026
@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f9282b68-46bb-443c-a9c7-5c8e748ef8ad

📥 Commits

Reviewing files that changed from the base of the PR and between a3ee694 and 8d863d0.

📒 Files selected for processing (2)
  • README.md
  • docs/src/routes/docs/api/memory-cache/+page.svx
✅ Files skipped from review due to trivial changes (2)
  • README.md
  • docs/src/routes/docs/api/memory-cache/+page.svx

📝 Walkthrough

Walkthrough

This PR makes MemoryCache.set reclaim TTL-expired entries before performing LRU eviction when a new key is inserted into a full cache. It updates the implementation, adds deterministic tests using fake timers, and revises README, API docs, and example pages to document the behavior.

Changes

TTL+MaxSize Pruning Order

Layer / File(s) Summary
set() method behavior and JSDoc
src/cache.ts
set() now calls prune() before evicting an LRU entry when inserting a new key causes size to exceed maxSize. JSDoc updated to document the ordering.
Test setup and TTL+maxSize pruning test
src/cache.lru.test.ts
Vitest fake timers enabled in beforeEach/afterEach. New test verifies that expired entries are pruned before selecting LRU candidates for eviction, asserting cache contents, hook callbacks, and stats.
README and API documentation
README.md, docs/src/routes/docs/api/memory-cache/+page.svx
API reference and README updated to state pruning-before-eviction; new TypeScript example demonstrates combined ttl + maxSize writes reclaim expired entries first.
LRU eviction example and descriptions
docs/src/routes/examples/+page.ts, docs/src/routes/examples/lru-eviction/+page.svelte
Example wording, imports, SEO metadata, and demo notes updated to explain that expired entries are reclaimed before evicting still-valid LRU entries; component description adjusted.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes


Possibly related PRs


Suggested labels

enhancement, documentation


Poem

⏰ In caches where old entries hide,
TTL whispers, then tides subside.
Prune first, evict last — a tidy feat,
Fresh keys arrive, the LRU keeps its seat.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'perf(cache): prune expired entries before eviction' directly and precisely summarizes the main change.
Description check ✅ Passed The description clearly details the change (prune before LRU eviction), testing approach, documentation updates, and verification steps.
Linked Issues check ✅ Passed All acceptance criteria from #161 are met: expired entries removed before LRU eviction, existing behavior unchanged without expired entries, and new tests added.
Out of Scope Changes check ✅ Passed All changes directly support the objective of pruning expired entries before max-size eviction and documenting the behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/prune-before-evict

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Around line 266-278: The README example is ambiguous about timing for ttl
expiry; update the MemoryCache example (referencing MemoryCache, ttl, maxSize
and the set calls for 'stale', 'fresh', 'next') to explicitly stagger the writes
or add a comment/note so only 'stale' expires before cache.set('next', ...). For
example, indicate a delay between cache.set('stale', ...) and cache.set('fresh',
...) (or insert an explicit wait/timeout comment) so readers know 'stale' is
allowed to expire while 'fresh' remains valid before calling cache.set('next',
...).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ef5e4986-a875-4203-a875-d0646c28e083

📥 Commits

Reviewing files that changed from the base of the PR and between 35abf79 and a3ee694.

📒 Files selected for processing (6)
  • README.md
  • docs/src/routes/docs/api/memory-cache/+page.svx
  • docs/src/routes/examples/+page.ts
  • docs/src/routes/examples/lru-eviction/+page.svelte
  • src/cache.lru.test.ts
  • src/cache.ts

Comment thread README.md
Stagger the TTL plus maxSize examples so readers can see that only the
first entry expires before the next write prunes it.
@jaysin586 jaysin586 merged commit 190aedc into main Jun 5, 2026
6 checks passed
@jaysin586

Copy link
Copy Markdown
Contributor Author

❌ Release workflow failed. Please check the workflow logs

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.

Prune expired entries before max-size eviction

1 participant