Skip to content

Fix/various bugs found#21

Merged
TKorr merged 6 commits intomainfrom
fix/various-bugs-found
Feb 19, 2026
Merged

Fix/various bugs found#21
TKorr merged 6 commits intomainfrom
fix/various-bugs-found

Conversation

@TKorr
Copy link
Contributor

@TKorr TKorr commented Feb 19, 2026

Summary

This branch fixes several correctness bugs discovered across cache policies and concurrent stores, and adds regression tests to prevent recurrence.

Bug Fixes

  • ConcurrentSlabStore TOCTOU race conditions — The old design used three separate RwLocks (for index, entries, and free list), creating time-of-check-to-time-of-use windows that could cause data corruption on concurrent update-after-remove, capacity overshoot under parallel inserts, and half-cleared state visible to readers during clear(). Refactored into a single SlabInner struct behind one RwLock to ensure atomicity across all mutations.

  • ARC ghost-list directory leak — The Case 4 (complete miss) path was not properly pruning ghost lists B1/B2, violating the ARC paper's invariant that directory size (T1+T2+B1+B2) ≤ 2×capacity. Fixed to match the paper's eviction logic and added GhostList::evict_lru() to support it.

  • Capacity-0 coercion in Clock, ClockPro, NRU — These policies silently coerced capacity=0 to capacity=1 via .max(1) in their constructors, inconsistent with the rest of the library. Now they honor capacity=0 and reject inserts gracefully.

  • MFU insert return-value bugMfuCore::insert at capacity=0 returned Some(value) (echoing the value back) instead of None. Fixed to return None for rejected inserts.

  • MRU / SLRU / TwoQ CoreCache::insert inconsistency — The CoreCache trait impl duplicated update-in-place logic that diverged from each type's inherent insert method. Unified by having the trait impl delegate directly to the inherent method. The inherent insert now returns Option<V> (old value on update, None on fresh insert).

  • ConcurrentWeightStore missing metricstry_insert and remove delegated to the inner store without updating the external metrics counters for inserts, updates, and removes.

Enhancements

  • ClockRing iterators — Added Iter, IterMut, IntoIter, Keys, Values, ValuesMut and IntoIterator impl for ClockRing.
  • ClockRing documentation — Improved module docs with rustdoc intra-doc links and updated the operations table.

Tests Added

  • tests/slab_concurrency.rs — Integration tests for TOCTOU update corruption, capacity overshoot, and atomic clear() under concurrency.
  • tests/policy_invariants.rs — Cross-policy invariant tests for capacity-0 semantics (Clock, ClockPro, NRU).
  • Per-policy unit regression tests for capacity-0 behavior, insert return values, and ARC ghost-list bounds.
  • ConcurrentWeightStore metrics tracking tests for inserts, updates, removes, hits, and misses.

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🧪 Test addition or modification

How Has This Been Tested?

  • Unit tests
  • Integration tests

Checklist

  • My code follows the project's coding standards
  • I have added tests for my changes
  • All new and existing tests pass (cargo test)
  • I have updated the documentation as needed

- Introduced regression tests across multiple cache policies (ARC, MFU, MRU, SLRU, TwoQ) to verify that caches with a capacity of 0 correctly reject inserts and maintain expected behavior.
- Added a new integration test file for cross-policy invariants to ensure consistent handling of capacity-0 across different cache implementations.
- Updated the tests README to include information about the new invariant tests, enhancing documentation clarity.
- Added `evict_lru` method to the ghost list for removing the least recently used key, enhancing eviction capabilities.
- Updated ARC and other policies to utilize the new LRU eviction method, ensuring efficient capacity management.
- Refined handling of capacity checks in various policies to prevent unnecessary evictions and improve performance.
- Adjusted tests to validate the new eviction behavior and ensure consistency across cache implementations.
- Updated operation table in `clock_ring.rs` to use links for method references, improving clarity and navigation.
- Changed `HashMap` to `FxHashMap` in documentation for better performance context.
- Added `Clone` derive to `Entry` and `ClockRing` structs to enhance usability in concurrent scenarios.
- Modified public API methods to accept borrowed keys, allowing for more flexible key types and reducing unnecessary clones.
- Improved documentation with concise examples for `clear`, `clear_shrink`, and `approx_bytes` methods, enhancing user understanding.
- Changed `HashMap` to `FxHashMap` in the documentation to reflect performance optimizations.
- Enhanced entry and ClockRing struct documentation to clarify key borrowing capabilities.
- Added details on lookup methods accepting borrowed keys, improving API usability.
- Updated examples and descriptions to align with recent changes in the public API.
- Introduced `Iter`, `IterMut`, `Keys`, `Values`, and `ValuesMut` iterators to `ClockRing`, allowing for flexible and efficient iteration over entries, keys, and values.
- Updated documentation to include new iterator methods and examples, improving clarity and user guidance.
- Enhanced the operation table to reflect the addition of iteration capabilities, ensuring comprehensive API coverage.
- Resolved TOCTOU race conditions in `ConcurrentSlabStore` by consolidating `RwLock`s for atomicity during updates and removals.
- Fixed ARC ghost-list directory leak to maintain invariant bounds during eviction.
- Updated capacity handling in `Clock`, `ClockPro`, and `NRU` policies to reject zero capacity inserts gracefully.
- Unified `CoreCache::insert` behavior across `MRU`, `SLRU`, and `TwoQ` policies for consistency.
- Added metrics tracking for `ConcurrentWeightStore` operations.
- Introduced new `GhostList::evict_lru()` method and iterators for `ClockRing`, along with integration tests for concurrency and policy invariants.
- Updated `ClockRing` documentation with improved clarity and expanded operations table.
@TKorr TKorr self-assigned this Feb 19, 2026
@TKorr TKorr merged commit 20cfd37 into main Feb 19, 2026
16 checks passed
@TKorr TKorr deleted the fix/various-bugs-found branch February 19, 2026 13:53
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.

1 participant