Extend lifecycle trait with on_evict_(cold|hot)#117
Conversation
There was a problem hiding this comment.
Pull request overview
Adds on_evict_hot and on_evict_cold hooks to the Lifecycle trait so callers can distinguish which queue an evicted entry came from (resolves #39). The existing on_evict becomes a deprecated, provided method to preserve source-level backwards compatibility, and shard.rs call sites are updated to dispatch to the appropriate new hook.
Changes:
- Add
on_evict_hot/on_evict_coldprovided methods onLifecycle, withon_evictnow#[deprecated]and given an empty default body that the new methods delegate to. - Update eviction call sites in
src/shard.rs(cold ring, hot ring, replacement ininsert_existing, placeholder rejection, and oversized-insert handlers) to call the new methods.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/lib.rs | Adds new trait methods, deprecates on_evict, and changes it from required to provided. |
| src/shard.rs | Replaces on_evict calls with on_evict_hot / on_evict_cold; uses enter_state to dispatch in insert_existing, unconditionally on_evict_hot in overweight/placeholder paths. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if let Some((idx, _)) = self.search_resident(hash, &key) { | ||
| if let Some((ek, ev)) = self.remove_internal(hash, idx) { | ||
| self.lifecycle.on_evict(lcs, ek, ev); | ||
| self.lifecycle.on_evict_hot(lcs, ek, ev); | ||
| } |
| @@ -1122,13 +1131,13 @@ impl< | |||
| // Make sure to remove any existing entry | |||
| if let Some((idx, _)) = self.search_resident(hash, &key) { | |||
| if let Some((ek, ev)) = self.remove_internal(hash, idx) { | |||
| self.lifecycle.on_evict(lcs, ek, ev); | |||
| self.lifecycle.on_evict_hot(lcs, ek, ev); | |||
| } | |||
| } | |||
| if matches!(strategy, InsertStrategy::Replace { .. }) { | |||
| return Err((key, value)); | |||
| } | |||
| self.lifecycle.on_evict(lcs, key, value); | |||
| self.lifecycle.on_evict_hot(lcs, key, value); | |||
| fn on_evict(&self, state: &mut Self::RequestState, key: Key, val: Val); | ||
| #[deprecated( | ||
| since = "0.6.22", | ||
| note = "Use `on_evict_hot` or `on_evict_cold` instead, depending on the desired semantics. This method will still be called by default to preserve backwards compatibility, but it won't be called if either of the new methods are implemented." |
| #[deprecated( | ||
| since = "0.6.22", | ||
| note = "Use `on_evict_hot` or `on_evict_cold` instead, depending on the desired semantics. This method will still be called by default to preserve backwards compatibility, but it won't be called if either of the new methods are implemented." | ||
| )] | ||
| #[allow(unused_variables)] | ||
| fn on_evict(&self, state: &mut Self::RequestState, key: Key, val: Val) {} |
| #[deprecated( | ||
| since = "0.6.22", | ||
| note = "Use `on_evict_hot` or `on_evict_cold` instead, depending on the desired semantics. This method will still be called by default to preserve backwards compatibility, but it won't be called if either of the new methods are implemented." | ||
| )] | ||
| #[allow(unused_variables)] | ||
| fn on_evict(&self, state: &mut Self::RequestState, key: Key, val: Val) {} | ||
|
|
||
| /// Called when an item is evicted from the cold queue. | ||
| #[inline] | ||
| fn on_evict_cold(&self, state: &mut Self::RequestState, key: Key, val: Val) { | ||
| #[allow(deprecated)] | ||
| self.on_evict(state, key, val) | ||
| } | ||
|
|
||
| /// Called when an item is evicted from the hot queue. | ||
| #[inline] | ||
| fn on_evict_hot(&self, state: &mut Self::RequestState, key: Key, val: Val) { | ||
| #[allow(deprecated)] | ||
| self.on_evict(state, key, val) | ||
| } |
- Fix hot/cold misclassification in handle_insert_overweight: capture the evicted entry's ResidentState before remove_internal so cold evictions aren't reported as hot. - Reword on_evict deprecation note to accurately describe per-method fallback (each new method delegates to on_evict independently). - Document rejection-style behavior on on_evict_hot: items that never enter the cache (oversized inserts and oversized placeholder values) are reported as hot. - Migrate DefaultLifecycle (sync and unsync) and the eviction_listener example to implement on_evict_hot/on_evict_cold directly.
|
Thanks @DenizUgur! I pushed a commit that addresses the Copilot review. Disposition per comment:
|
|
So to make sure I understand correctly, if I were to use UnitWeighter and the queue is full do the new items reported as hot evictions? |
…cold - on_evict stays as a provided method with an empty default body (no deprecation). on_evict_hot/on_evict_cold default to delegating to it, so existing impls keep working and new impls can override just the hot/cold methods when they want to distinguish. - Route oversized inserts and oversized placeholder rejections through on_evict_cold (they never entered any queue). - Revert DefaultLifecycle (sync/unsync) and the eviction_listener example to the simple on_evict form.
|
It depends on the state of the cache, you can get both cold and hot evictions regardless of Weighter. |
| /// | ||
| /// If none of `on_evict`, `on_evict_hot`, or `on_evict_cold` is overridden, | ||
| /// eviction notifications are silently dropped. | ||
| #[allow(unused_variables)] | ||
| #[inline] | ||
| fn on_evict(&self, state: &mut Self::RequestState, key: Key, val: Val) {} |
| self.entries.remove(placeholder.idx()); | ||
| self.map_remove(placeholder.hash(), placeholder.idx()); | ||
| self.lifecycle.on_evict(lcs, key, value); | ||
| self.lifecycle.on_evict_cold(lcs, key, value); |
| /// Called when an item is evicted from the hot queue. | ||
| /// | ||
| /// By default delegates to [`Lifecycle::on_evict`]. | ||
| #[inline] | ||
| fn on_evict_hot(&self, state: &mut Self::RequestState, key: Key, val: Val) { | ||
| self.on_evict(state, key, val) | ||
| } |
Added new
on_evict_coldandon_evict_hotmethods toLifecycletrait to be able to distinguish where the resident is being evicted from. This is useful for tracking the age of the evicted residents.fixes #39