Conversation
d836942 to
d6a388f
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds a new closure-based “inspect and act” entry API to the cache, enabling atomic keep/remove/replace decisions for existing entries while preserving placeholder-based single-loader semantics (sync + async), addressing the upsert/replace use cases in #73 and #77.
Changes:
- Introduces
entry/entry_async(read-lock fast path) andentry_mut/entry_mut_async(write-lock, in-place mutation + weight recalculation) returningEntryResult. - Adds shard support for
entry_or_placeholder,get_key_value, and renames placeholder upsert helper toget_or_placeholder. - Expands documentation and adds extensive unit + shuttle concurrency tests for the new APIs.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/sync.rs | Adds new entry APIs (sync + async) and many tests exercising actions, placeholder waiting, and timeouts |
| src/shard.rs | Adds shard-level EntryOrPlaceholder, entry_or_placeholder, and get_key_value helper; renames placeholder helper |
| src/sync_placeholder.rs | Adds OccupiedAction/EntryResult, refactors placeholder join logic, and exposes wait_for_placeholder for reuse |
| src/unsync.rs | Updates to renamed shard placeholder helper and fixes docstrings |
| src/shuttle_tests.rs | Adds shuttle stress/race tests covering new entry APIs |
| src/lib.rs | Documents the new entry API family in crate-level docs and fixes wording |
| src/options.rs | Fixes doc typo (Option → Options) |
| README.md | Documents entry/entry_mut API and fixes minor wording |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
src/sync_placeholder.rs
Outdated
| let start = *timeout_start.get_or_insert_with(Instant::now); | ||
| #[cfg(not(fuzzing))] | ||
| thread::park_timeout(remaining); | ||
| timeout = Some(remaining.saturating_sub(start.elapsed())); | ||
| *timeout = Some(remaining.saturating_sub(start.elapsed())); |
src/sync.rs
Outdated
| // Read-lock fast path: if key exists and callback returns Keep, we're done | ||
| // without ever taking a write lock. | ||
| { | ||
| let shard_guard = shard.read(); | ||
| if let Some((k, v)) = shard_guard.get_key_value(hash, key) { | ||
| match on_occupied(k, v) { | ||
| OccupiedAction::Keep(t) => return EntryResult::Value(t), | ||
| OccupiedAction::Remove | OccupiedAction::Replace => { | ||
| // Need write lock — fall through | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Write-lock path: re-call callback for authoritative decision, or handle | ||
| // vacant/placeholder cases. |
src/sync.rs
Outdated
| { | ||
| let shard_guard = shard.read(); | ||
| if let Some((k, v)) = shard_guard.get_key_value(hash, key) { | ||
| match on_occupied(k, v) { | ||
| OccupiedAction::Keep(t) => return EntryResult::Value(t), | ||
| OccupiedAction::Remove | OccupiedAction::Replace => {} | ||
| } | ||
| } |
src/shard.rs
Outdated
| // Create placeholder in the same slot | ||
| let shared = Plh::new(hash, idx); | ||
| let (entry, _) = self.entries.get_mut(idx).unwrap(); | ||
| *entry = Entry::Placeholder(Placeholder { | ||
| key: key.to_owned(), | ||
| hot: state, | ||
| shared: shared.clone(), |
There was a problem hiding this comment.
Pull request overview
Adds new entry/entry_mut (and async variants) to the sync cache, enabling atomic “inspect-and-act” operations on existing entries (keep/remove/replace) while preserving placeholder-based single-loader deduplication on misses.
Changes:
- Introduces
entry()/entry_async()with a read-lock “Keep” fast path and write-lock fallback forRemove/Replace. - Introduces
entry_mut()/entry_mut_async()for in-place mutation under a write lock with post-callback weight recalculation. - Adds shard-level support (
get_key_value,entry_or_placeholder) and expands docs/tests (including Shuttle concurrency tests) to cover the new API.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/sync.rs | Adds the public entry* APIs, exports new enums, and adds extensive unit tests. |
| src/sync_placeholder.rs | Adds EntryResult/OccupiedAction types and factors out placeholder waiting logic for reuse by entry*. |
| src/shard.rs | Adds get_key_value, renames placeholder helper, and implements entry_or_placeholder to support entry*. |
| src/unsync.rs | Updates unsync code to use renamed placeholder helper. |
| src/shuttle_tests.rs | Adds Shuttle concurrency tests covering entry_mut* and related wakeup races. |
| src/lib.rs | Documentation updates referencing the new entry APIs and minor wording fixes. |
| src/options.rs | Fixes a docstring typo (“Option” → “Options”). |
| README.md | Documents the new entry / entry_mut API with an example and minor typo fix. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| loop { | ||
| if let Some(remaining) = timeout { | ||
| if let Some(remaining) = *timeout { | ||
| if remaining.is_zero() { | ||
| return Self::join_timeout(lifecycle, shard, shared, parked_thread, ¬ified); | ||
| } | ||
| let start = *timeout_start.get_or_insert_with(Instant::now); | ||
| let start = Instant::now(); | ||
| #[cfg(not(fuzzing))] | ||
| thread::park_timeout(remaining); | ||
| timeout = Some(remaining.saturating_sub(start.elapsed())); | ||
| *timeout = Some(remaining.saturating_sub(start.elapsed())); | ||
| } else { |
There was a problem hiding this comment.
Pull request overview
This PR introduces a new closure-based entry / entry_mut API to the concurrent cache to support atomic “inspect-and-act” operations (keep/remove/replace) while preserving placeholder-based deduplication for cache misses and concurrent loaders.
Changes:
- Added
entry/entry_async(read-lock fast path forKeep) andentry_mut/entry_mut_async(in-place mutation under write lock with weight recalculation). - Introduced
OccupiedAction<T>andEntryResult<T>enums and extended placeholder waiting to support timeout propagation across retries. - Refactored shard placeholder acquisition (
get_or_placeholder) and addedget_key_valueplus extensive sync + shuttle concurrency tests and docs/README updates.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/sync.rs |
Adds the new public entry* APIs, wires them into shard/placeholder logic, and adds comprehensive tests. |
src/sync_placeholder.rs |
Adds OccupiedAction/EntryResult, extends GuardResult, and refactors placeholder waiting with deadline reuse. |
src/shard.rs |
Adds get_key_value, renames placeholder upsert to get_or_placeholder, and introduces entry_or_placeholder shard primitive. |
src/unsync.rs |
Updates unsync placeholder acquisition to use the renamed shard API. |
src/shuttle_tests.rs |
Adds shuttle-based concurrency tests for the new entry APIs (sync + async). |
src/lib.rs |
Updates crate-level docs to mention the new entry APIs and fixes minor wording. |
src/options.rs |
Minor doc comment correction. |
README.md |
Documents the new entry API with an example and fixes minor wording. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
Adds a new closure-based “inspect-and-act” entry API to the synchronous cache to enable atomic keep/remove/replace (and mutable in-place updates) while integrating with the existing placeholder/guard deduplication mechanism.
Changes:
- Introduces
entry/entry_async(shared ref callback with read-lock fast path) andentry_mut/entry_mut_async(mutable callback under write lock) plusOccupiedAction+EntryResult. - Refactors placeholder acquisition (
upsert_placeholder→get_or_placeholder) and adds shard helperget_key_value()to support the read-lock occupied fast path. - Expands tests substantially (including shuttle concurrency tests) and updates docs/README wording for the new API.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/sync.rs | Implements new entry* APIs, integrates placeholder waiting/retry, and adds extensive unit + async tests. |
| src/shard.rs | Adds OccupiedAction, EntryOrPlaceholder, entry_or_placeholder, and get_key_value() to support atomic entry operations. |
| src/sync_placeholder.rs | Adds EntryResult, re-exports OccupiedAction, and updates placeholder wait logic to use a reusable deadline. |
| src/shuttle_tests.rs | Adds shuttle tests for the new entry APIs and waker-change race coverage. |
| src/unsync.rs | Updates unsync placeholder calls to the renamed get_or_placeholder API and fixes doc wording. |
| src/lib.rs | Updates crate-level docs to mention the new entry API and fixes minor wording. |
| src/options.rs | Fixes a doc typo (“Option” → “Options”). |
| README.md | Mentions and demonstrates the new entry API; fixes minor wording. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
64522a3 to
3318018
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new closure-based entry() / entry_async() API to the synchronous cache to support atomic inspect-and-act (keep/remove/replace) under a shard write lock, integrating with existing placeholder/guard deduplication for cache misses and concurrent loaders.
Changes:
- Introduces
Cache::entry/Cache::entry_asyncreturningEntryResult, driven byOccupiedActiondecisions made under a shard write lock. - Refactors placeholder join/wait logic (sync + async), including a
!UnpinJoinFutureto safely store waiter notification pointers. - Updates shard internals to support entry-or-placeholder behavior and renames placeholder creation API (
upsert_placeholder→get_or_placeholder), plus doc/test updates.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/unsync.rs | Renames placeholder API usage and fixes doc typos in the unsync cache. |
| src/sync_placeholder.rs | Adds EntryResult/JoinResult, refactors join/wait mechanics, and makes JoinFuture pin-safe. |
| src/sync.rs | Adds entry/entry_async, updates async guard behavior, adjusts re-exports, and adds extensive tests. |
| src/shuttle_tests.rs | Adds Shuttle concurrency tests covering the new entry APIs and waker-change races. |
| src/shard.rs | Adds OccupiedAction + shard-level entry_or_placeholder, introduces get_key_value, renames placeholder getter. |
| src/options.rs | Fixes doc typo (Option → Options). |
| src/lib.rs | Updates crate-level docs to mention the new entry family and fixes wording. |
| README.md | Documents the new entry API and fixes a wording typo in the example. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
c83ec93 to
c249def
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds a new closure-based entry() / entry_async() API to the concurrent cache to support atomic inspect-and-act patterns under a shard write lock, integrating with the existing placeholder/guard mechanism for single-flight loading and adding tests/docs around the new behavior.
Changes:
- Introduces
EntryAction<T>/EntryResult<T>and implementsCache::entry+Cache::entry_asyncfor atomic mutate/remove/replace-or-guard flows. - Refactors placeholder join/waiting code to support deduplication and async joining without cloning in the join future itself.
- Updates docs/README and expands test coverage (including shuttle tests) for the new entry behavior and concurrency scenarios.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/unsync.rs | Updates placeholder acquisition API name + minor doc fixes. |
| src/sync_placeholder.rs | Adds EntryResult, refactors join/wait logic, makes join future !Unpin and internal. |
| src/sync.rs | Exposes entry/entry_async, integrates placeholder waiting, adjusts exports. |
| src/shard.rs | Adds EntryAction + shard-level entry_or_placeholder and weight guard logic. |
| src/shuttle_tests.rs | Adds shuttle concurrency tests for entry/entry_async. |
| src/options.rs | Fixes doc typo (Option → Options). |
| src/lib.rs | Documentation improvements mentioning entry API + typo fix. |
| README.md | Documents new entry API and fixes typos. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| let list_head = if state == ResidentState::Hot { | ||
| self.num_hot -= 1; | ||
| self.weight_hot -= old_weight; | ||
| &mut self.hot_head | ||
| } else { |
src/sync.rs
Outdated
| pub use crate::sync_placeholder::{ | ||
| EntryResult, GuardResult, EntryAction, PlaceholderGuard, | ||
| }; | ||
| use crate::sync_placeholder::{JoinFuture, JoinResult}; |
d0e1fa6 to
55e7df7
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces a new closure-based entry() / entry_async() API on the concurrent (sync) cache to support atomic “inspect-and-act” updates under a shard write lock, while preserving existing placeholder deduplication behavior and improving panic-safety for weight accounting.
Changes:
- Add
Cache::entryandCache::entry_asyncwithEntryAction/EntryResultto support retain/remove/replace-with-guard patterns. - Refactor placeholder join/wait logic (sync + async) to support retries and make async waiting pin-safe.
- Adjust shard internals to support entry-or-placeholder operations and panic-safe weight recalculation; update docs/tests accordingly.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/unsync.rs | Renames placeholder upsert helper usage; minor doc fixes. |
| src/sync_placeholder.rs | Adds EntryResult, refactors join/wait logic, and makes JoinFuture pin-stable for waiter pointer safety. |
| src/sync.rs | Exposes entry/entry_async, updates async guard logic, and adds extensive tests. |
| src/shuttle_tests.rs | Adds shuttle-based concurrency tests covering new entry APIs and waker-change races. |
| src/shard.rs | Adds EntryAction + shard-level entry_or_placeholder, renames placeholder helper to get_or_placeholder, introduces panic-safe WeightGuard. |
| src/options.rs | Small docs correction (“Options” vs “Option”). |
| src/lib.rs | Docs updates mentioning the new entry API; minor wording fixes. |
| README.md | Documents the new entry API with examples; minor wording fixes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
- Add `entry()` / `entry_async()` with `FnOnce(&Key, &mut Val) -> EntryAction<T>` for atomic inspect-and-act under a write lock - `EntryAction<T>`: `Retain(T)`, `Remove`, `ReplaceWithGuard` - `EntryResult<T>`: `Retained(T)`, `Removed(K, V)`, `Replaced(Guard, V)`, `Vacant(Guard)`, `Timeout` - Placeholder deduplication: concurrent callers wait (blocking or async) and retry - Panic-safe weight accounting via `WeightGuard` drop guard - Shuttle concurrency tests and docs/README updates Closes #73, closes #77
Add
entry()/entry_async()methods that take aFnOnce(&Key, &mut Val) -> EntryAction<T>closure for atomic inspect-and-act patterns under a write lock, with weight recalculation onRetain.EntryAction<T>enum:Retain(T),Remove,ReplaceWithGuardEntryResult<T>enum:Retained(T),Removed(K, V),Replaced(PlaceholderGuard, V),Vacant(PlaceholderGuard),TimeoutWeightGuarddrop guardCloses #73, closes #77