Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,36 @@ pub trait Lifecycle<Key, Val> {
fn before_evict(&self, state: &mut Self::RequestState, key: &Key, val: &mut Val) {}

/// Called when an item is evicted.
fn on_evict(&self, state: &mut Self::RequestState, key: Key, val: Val);
///
/// To distinguish evictions from the hot vs cold queues, override
/// [`Lifecycle::on_evict_hot`] and/or [`Lifecycle::on_evict_cold`] instead;
/// they default to delegating here.
///
/// 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) {}
Comment on lines +203 to +212

/// Called when an item is evicted from the cold queue.
///
/// By default delegates to [`Lifecycle::on_evict`].
///
/// Note: items that are rejected without ever being admitted to the cache
/// (oversized inserts and oversized placeholder values) are also reported
/// via this method.
#[inline]
fn on_evict_cold(&self, state: &mut Self::RequestState, key: Key, val: Val) {
self.on_evict(state, key, val)
}

/// 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)
}
Comment on lines +226 to +235

/// Called after a request finishes, e.g.: insert, replace.
///
Expand Down
27 changes: 20 additions & 7 deletions src/shard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,8 @@ impl<
if self.num_non_resident > self.capacity_non_resident {
self.advance_ghost();
}
self.lifecycle.on_evict(lcs, evicted.key, evicted.value);
self.lifecycle
.on_evict_cold(lcs, evicted.key, evicted.value);
return true;
}
}
Expand Down Expand Up @@ -835,7 +836,7 @@ impl<
unsafe { core::hint::unreachable_unchecked() };
};
self.hot_head = next;
self.lifecycle.on_evict(lcs, evicted.key, evicted.value);
self.lifecycle.on_evict_hot(lcs, evicted.key, evicted.value);
self.map_remove(hash, idx);
}
return true;
Expand Down Expand Up @@ -920,7 +921,15 @@ impl<
} else if evicted_weight != 0 && weight == 0 {
*list_head = self.entries.unlink(idx);
}
self.lifecycle.on_evict(lcs, evicted.key, evicted.value);
match enter_state {
ResidentState::Hot => {
self.lifecycle.on_evict_hot(lcs, evicted.key, evicted.value)
}
ResidentState::Cold => {
self.lifecycle
.on_evict_cold(lcs, evicted.key, evicted.value)
}
}
}
Entry::Ghost(_) => {
self.weight_hot += weight;
Expand Down Expand Up @@ -1052,7 +1061,7 @@ impl<
) -> Result<(), 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);
Ok(())
}

Expand Down Expand Up @@ -1120,15 +1129,19 @@ impl<
strategy: InsertStrategy,
) -> Result<(), (Key, Val)> {
// Make sure to remove any existing entry
if let Some((idx, _)) = self.search_resident(hash, &key) {
if let Some((idx, resident)) = self.search_resident(hash, &key) {
let prev_state = resident.state;
if let Some((ek, ev)) = self.remove_internal(hash, idx) {
self.lifecycle.on_evict(lcs, ek, ev);
match prev_state {
ResidentState::Hot => self.lifecycle.on_evict_hot(lcs, ek, ev),
ResidentState::Cold => self.lifecycle.on_evict_cold(lcs, ek, ev),
}
}
}
if matches!(strategy, InsertStrategy::Replace { .. }) {
return Err((key, value));
}
self.lifecycle.on_evict(lcs, key, value);
self.lifecycle.on_evict_cold(lcs, key, value);
Ok(())
}

Expand Down
3 changes: 0 additions & 3 deletions src/unsync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,9 +443,6 @@ impl<Key, Val> Lifecycle<Key, Val> for DefaultLifecycle<Key, Val> {

#[inline]
fn begin_request(&self) -> Self::RequestState {}

#[inline]
fn on_evict(&self, _state: &mut Self::RequestState, _key: Key, _val: Val) {}
}

#[derive(Debug, Clone)]
Expand Down
Loading