[−][src]Struct associative_cache::entry::Entry
A potentially-empty entry in a cache, used to perform get-or-create operations on the cache.
Constructed via the AssociativeCache::entry
method.
Methods
impl<'a, K, V, C, I, R> Entry<'a, K, V, C, I, R> where
C: Capacity,
I: Indices<K, C>,
R: Replacement<V, C>,
[src]
C: Capacity,
I: Indices<K, C>,
R: Replacement<V, C>,
pub fn or_insert_with(
self,
make_key: impl FnOnce() -> K,
make_val: impl FnOnce() -> V
) -> &'a mut V
[src]
self,
make_key: impl FnOnce() -> K,
make_val: impl FnOnce() -> V
) -> &'a mut V
Get the underlying cached data, creating and inserting it into the cache if it doesn't already exist.
Differences from std::collections::HashMap
's Entry
API
std::collections::HashMap
's Entry
API takes unconditional ownership
of the query key, even in scenarios where there is already an entry with
that key in the map. This means that if your keys are expensive to
create (like String
and its heap allocation) that you have to eagerly
construct the key even if you don't end up needing it.
In contrast, the associative_cache::Entry
API allows you to get an
Entry
with just a borrow of a key, allowing you to delay the
potentially-expensive key construction until we actually need
it. However, this is not without drawbacks. Now the or_insert_with
method needs a way to construct an owned key: the make_key
parameter
here. make_key
must return an owned key that is equivalent to the
borrowed key that was used to get this Entry
. Failure to do this
will result in an invalid cache (likely manifesting as wasted entries
that take up space but can't ever be queried for).
Example
use associative_cache::*; let mut cache = AssociativeCache::< String, usize, Capacity4, HashTwoWay, RoundRobinReplacement, >::default(); // Get or create an entry for "hi", delaying the `&str` to `String` // allocation until if/when we actually insert into the cache. let val = cache.entry("hi").or_insert_with( || "hi".to_string(), || 42, ); // The cache was empty, so we inserted the default value of 42. assert_eq!(*val, 42); // We can modify the value. *val += 1;
pub fn take_entry_that_will_be_replaced(&mut self) -> Option<(K, V)>
[src]
If inserting into this Entry
will replace another entry in the
cache, remove that other entry from the cache and return it now.
Example
use associative_cache::*; let mut cache = AssociativeCache::< String, usize, Capacity256, HashTwoWay, RoundRobinReplacement, >::default(); cache.insert("hi".to_string(), 5); let mut entry = cache.entry("bye"); // Because this entry could replace the entry for "hi" depending on the hash // function in use, we have an opportunity to recover the // about-to-be-replaced entry here. if let Some((key, val)) = entry.take_entry_that_will_be_replaced() { assert_eq!(key, "hi"); assert_eq!(val, 5); } let val = entry.or_insert_with(|| "bye".into(), || 1337); assert_eq!(*val, 1337);
Trait Implementations
impl<'a, K, V, C, I, R> Debug for Entry<'a, K, V, C, I, R> where
C: Capacity,
R: Replacement<V, C>,
[src]
C: Capacity,
R: Replacement<V, C>,
Auto Trait Implementations
impl<'a, K, V, C, I, R> Send for Entry<'a, K, V, C, I, R> where
C: Send,
I: Send,
K: Send,
R: Send,
V: Send,
C: Send,
I: Send,
K: Send,
R: Send,
V: Send,
impl<'a, K, V, C, I, R> Sync for Entry<'a, K, V, C, I, R> where
C: Sync,
I: Sync,
K: Sync,
R: Sync,
V: Sync,
C: Sync,
I: Sync,
K: Sync,
R: Sync,
V: Sync,
impl<'a, K, V, C, I, R> Unpin for Entry<'a, K, V, C, I, R>
impl<'a, K, V, C, I, R> RefUnwindSafe for Entry<'a, K, V, C, I, R> where
C: RefUnwindSafe,
I: RefUnwindSafe,
K: RefUnwindSafe,
R: RefUnwindSafe,
V: RefUnwindSafe,
C: RefUnwindSafe,
I: RefUnwindSafe,
K: RefUnwindSafe,
R: RefUnwindSafe,
V: RefUnwindSafe,
impl<'a, K, V, C, I, R> !UnwindSafe for Entry<'a, K, V, C, I, R>
Blanket Implementations
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
V: MultiLane<T>,