Cache

Struct Cache 

Source
pub struct Cache<K, V> { /* private fields */ }
Expand description

Cache implementation with a focus on expiry duration and reducing IO calls.

It is based on the HashMap APIs, so it can be used in almost the same way.

§Examples

use cache_cache::Cache;
use std::{thread, time::Duration};

// Create a new Cache with 10ms expiry duration.
let mut c = Cache::with_expiry_duration(Duration::from_millis(10));

// Insert a new value in the cache
c.insert("present_temperature", 27.0);

// Retrieve it
assert_eq!(c.get(&"present_temperature"), Some(&27.0));

// Wait for the value to get expired
thread::sleep(Duration::from_millis(20));
assert_eq!(c.get(&"present_temperature"), None);

Implementations§

Source§

impl<K, V> Cache<K, V>
where K: Hash + Eq, V: Clone + Copy,

Source

pub fn keep_last() -> Self

Creates an empty Cache where the last inserted value is kept.

§Examples
use cache_cache::Cache;
let mut cache: Cache<&str, i32> = Cache::keep_last();
Source

pub fn with_expiry_duration(duration: Duration) -> Self

Creates an empty Cache with an expiry duration.

Each inserted value is kept until its expiration duration is reached.

§Examples
use cache_cache::Cache;
use std::time::Duration;

let mut cache: Cache<&str, i32> = Cache::with_expiry_duration(Duration::from_millis(10));
Source

pub fn entry(&mut self, key: K) -> Entry<'_, K, V>

Gets the given key’s corresponding entry in the cache for in-place manipulation.

Examples

use cache_cache::Cache;
use std::time::Duration;

let mut motors_temperature = Cache::with_expiry_duration(Duration::from_millis(100));

fn get_motor_temperature(motor_id: &u8) -> f64 {
    // Should actually retrieve the real value from the motor
    42.0
}

let temp = motors_temperature.entry(11).or_insert_with(get_motor_temperature);
assert_eq!(motors_temperature.get(&11), Some(&42.0));
Source

pub fn entries<'a>(&'a mut self, keys: &'a [K]) -> Entries<'_, K, V>

Gets the given keys’ corresponding entries in the cache for in-place manipulation.

This is mostly useful if you want to modify multiple entries at once. For instance, because you can use a single IO call to update all those entries instead of having a call for each entry.

Examples

use cache_cache::Cache;
use std::{error::Error, time::Duration};

fn get_position(ids: &[u8]) -> Result<Vec<f64>, Box<dyn Error>> {
    // For simplicity, this function always work.
    // But it's a mockup for a real world scenario where hardware IO can fail.
    Ok(ids.iter().map(|&id| id as f64 * 10.0).collect())
}

let mut present_position = Cache::with_expiry_duration(Duration::from_millis(10));

present_position.insert(10, 0.0);

let pos = present_position
    .entries(&[10, 11, 12])
    .or_try_insert_with(get_position);

assert!(pos.is_ok());
assert_eq!(pos.unwrap(), vec![0.0, 110.0, 120.0]);
Source

pub fn get<Q>(&self, k: &Q) -> Option<&V>
where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

Returns a reference to the value corresponding to the key if it has not expired.

§Examples
use cache_cache::Cache;

let mut cache: Cache<&str, f64> = Cache::keep_last();
cache.insert("position", 0.23);
assert_eq!(cache.get(&"position"), Some(&0.23));
Source

pub fn insert(&mut self, k: K, v: V) -> Option<V>

Inserts a key-value pair into the cache.

If the cache did not have this key present, None is returned. If the cache did have this key present, the value is updated, and the old value (expired or not) is returned.

Examples

use cache_cache::Cache;

let mut cache = Cache::keep_last();
assert_eq!(cache.insert(10, "a"), None);
assert_eq!(cache.insert(10, "b"), Some("a"));
assert_eq!(cache[&10], "b");

Trait Implementations§

Source§

impl<K: Debug, V: Debug> Debug for Cache<K, V>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<K, Q, V> Index<&Q> for Cache<K, V>
where K: Eq + Hash + Borrow<Q>, Q: Eq + Hash + ?Sized, V: Clone + Copy,

Source§

fn index(&self, index: &Q) -> &Self::Output

Returns a reference to the value corresponding to the supplied key.

§Panics

Panics if the key is not present in the Cache.

Source§

type Output = V

The returned type after indexing.

Auto Trait Implementations§

§

impl<K, V> Freeze for Cache<K, V>

§

impl<K, V> RefUnwindSafe for Cache<K, V>

§

impl<K, V> Send for Cache<K, V>
where K: Send, V: Send,

§

impl<K, V> Sync for Cache<K, V>
where K: Sync, V: Sync,

§

impl<K, V> Unpin for Cache<K, V>
where K: Unpin, V: Unpin,

§

impl<K, V> UnwindSafe for Cache<K, V>
where K: UnwindSafe, V: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.