Struct hashlru::SyncCache

source ·
pub struct SyncCache<K, V>
where K: Eq + Hash + Clone, V: Clone,
{ /* private fields */ }
Expand description

Thread-safe LRU cache.

This is similar to the standard, non thread-safe version, with the following differences:

  • thread-safe, it is safe to call concurrently
  • get/peek return copies, so keys and values need to implement Clone
  • no iterators, only flat dumps to export data
  • no Serde support, use dumps to dump/restore from cold state

§Examples

use hashlru::SyncCache;

// Does not need to be `mut`
let cache = SyncCache::new(4);
cache.insert("key1", 10);
cache.insert("key2", 20);
cache.insert("key3", 30);
cache.insert("key4", 40);
cache.insert("key5", 50);
// key1 has been dropped, size is limited to 4
assert_eq!(Some("key2"), cache.lru());
assert_eq!(Some(20), cache.get(&"key2"));
// getting key2 has made key3 the least recently used item
assert_eq!(Some("key3"), cache.lru());
assert_eq!(Some(40), cache.get(&"key4"));
// getting key4 makes it the most recently used item
assert_eq!("[sync] [key3: 30, key5: 50, key2: 20, key4: 40]", format!("{}", cache));

Implementations§

source§

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

source

pub fn len(&self) -> usize

Returns the number of elements in the map.

§Examples
use hashlru::SyncCache;

let a = SyncCache::new(10);
assert_eq!(a.len(), 0);
a.insert(1, "a");
assert_eq!(a.len(), 1);
source

pub fn capacity(&self) -> usize

Returns the max number of elements in the map.

§Examples
use hashlru::SyncCache;

let a: SyncCache::<u32,String> = SyncCache::new(10);
assert_eq!(a.capacity(), 10);
source

pub fn is_empty(&self) -> bool

Returns true if cache is empty

§Examples
use hashlru::SyncCache;

let a: SyncCache::<u32,String> = SyncCache::new(10);
assert!(a.is_empty());
a.insert(0, String::from("hello"));
assert!(!a.is_empty());
source

pub fn is_full(&self) -> bool

Returns true if cache is full

§Examples
use hashlru::SyncCache;

let a: SyncCache::<usize,usize> = SyncCache::new(10);
assert!(!a.is_full());
for i in 0..10 {
    a.insert(i, i);
}
assert!(a.is_full());
source

pub fn clear(&self)

Clears the LRU cache, drops all data. Keeps the current capacity setting.

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
lru.insert("x", 1);
lru.insert("y", 10);

lru.clear();
assert_eq!(0, lru.len());
assert_eq!(10, lru.capacity());
source

pub fn new(capacity: usize) -> SyncCache<K, V>

Crate a new LRU. The capacity needs to be specified, as a 0-sized LRU can hold no data at all.

It is possible to resize it later.

§Examples
use hashlru::SyncCache;

let lru: SyncCache<String, usize> = SyncCache::new(100);
source

pub fn resize(&self, capacity: usize) -> usize

Resizes the LRU cache. Drops least recently used entries in priority when size is reduced below current length.

Returns the number of dropped entries, if any.

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
lru.insert("x", 1);
lru.insert("y", 10);
lru.insert("z", 100);
lru.insert("t", 1000);
lru.insert("u", 10000);

assert_eq!(2, lru.resize(3));
assert_eq!(3, lru.len());
assert_eq!(3, lru.capacity());
source

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

Inserts a key-value pair into the map.

If the key already exists, returns the previous value for this key.

§Examples
use hashlru::SyncCache;
let lru = SyncCache::new(10);

assert_eq!(None, lru.insert(1, "a"));
assert!(lru.contains_key(&1));
assert!(!lru.contains_key(&2));
assert_eq!(Some("a"), lru.insert(1, "b"));
assert_eq!(Some("b"), lru.get(&1));
source

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

Pushes a key-value pair into the map.

If one entry needs to be removed because the cache is full, return the entry that was removed.

§Examples
use hashlru::SyncCache;
let lru = SyncCache::new(10);

lru.push(1, "a");
assert_eq!(lru.contains_key(&1), true);
assert_eq!(lru.contains_key(&2), false);
source

pub fn get(&self, k: &K) -> Option<V>

Returns a reference to the value corresponding to the key.

Since this is a LRU, reading alters the order of the items and will place this one first, as it is now the most recently used.

§Examples
use hashlru::SyncCache;

let cache = SyncCache::new(10);
cache.insert(1, "a");
cache.insert(2, "b");
assert_eq!(Some(1), cache.lru());
assert_eq!(cache.get(&1), Some("a"));
assert_eq!(Some(2), cache.lru());
assert_eq!(cache.get(&3), None);
source

pub fn bump(&self, k: &K)

Bumps a key, making it the most recently used key (MRU).

This is similar to doing a get() and ignore the value.

§Examples
use hashlru::SyncCache;

let cache = SyncCache::new(10);
cache.insert(1, "a");
cache.insert(2, "b");
assert_eq!(Some(1), cache.lru());
cache.bump(&1);
assert_eq!(Some(2), cache.lru());
source

pub fn get_key_value(&self, k: &K) -> Option<(K, V)>

Returns a reference to the value corresponding to the key, along with the key itself.

Since this is a LRU, reading alters the order of the items and will place this one first, as it is now the most recently used.

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
lru.insert(1, "a");
assert_eq!(Some((1, "a")), lru.get_key_value(&1));
assert_eq!(None, lru.get(&2));
source

pub fn peek(&self, k: &K) -> Option<V>

Returns a reference to the value corresponding to the key.

This is different from a standard get, it will not alter the order of items, and is a read-only operation.

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
lru.insert(1, "a");
assert_eq!(lru.peek(&1), Some("a"));
assert_eq!(lru.peek(&2), None);
source

pub fn peek_key_value(&self, k: &K) -> Option<(K, V)>

Returns a reference to the value corresponding to the key, along with the key itself.

This is different from a standard get_key_value, it will not alter the order of items, and is a read-only operation.

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
lru.insert(1, "a");
assert_eq!(Some((1, "a")), lru.peek_key_value(&1));
assert_eq!(None, lru.peek(&2));
source

pub fn contains_key(&self, k: &K) -> bool

Returns true if there is a value for the specified key.

It does not alter the order of items, and is a read-only operation.

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
lru.insert(421, true);
assert!(lru.contains_key(&421));
assert!(!lru.contains_key(&33));
source

pub fn lru(&self) -> Option<K>

Returns the least recently used key (LRU).

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
assert_eq!(None, lru.lru());
lru.push("abc", true);
assert_eq!(Some("abc"), lru.lru());
lru.push("def", false);
assert_eq!(Some("abc"), lru.lru());
lru.get(&"abc");
assert_eq!(Some("def"), lru.lru());
source

pub fn pop_lru(&self) -> Option<(K, V)>

Pops the least recently used key, returning its value if the cache was non-empty.

After it has been popped, it is no more in the cache.

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
assert_eq!(None, lru.pop_lru());
lru.push("abc", true);
lru.push("def", false);
assert_eq!(Some(("abc", true)), lru.pop_lru());
assert_eq!(1, lru.len());
source

pub fn get_lru(&self) -> Option<(K, V)>

Gets the least recently used key, returning its value if the cache was non-empty.

After it is returned, it becomes the most recently used item, so a next call to get_lru() would return a different value.

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
assert_eq!(None, lru.pop_lru());
lru.push("abc", true);
lru.push("def", false);
assert_eq!(Some(("abc", true)), lru.get_lru());
assert_eq!(2, lru.len());
assert_eq!(Some("def"), lru.lru());
source

pub fn peek_lru(&self) -> Option<(K, V)>

Peeks the least recently used key, returning its value if the cache was non-empty.

This does not alter the order of the cache.

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
assert_eq!(None, lru.peek_lru());
lru.push("abc", true);
lru.push("def", false);
assert_eq!(Some(("abc", true)), lru.peek_lru());
assert_eq!(2, lru.len());
assert_eq!(Some("abc"), lru.lru());
source

pub fn mru(&self) -> Option<K>

Similar to mru() but returns the key, not only a reference to it.

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
assert_eq!(None, lru.mru());
lru.push("abc", true);
assert_eq!(Some("abc"), lru.mru());
lru.push("def", false);
assert_eq!(Some("def"), lru.mru());
lru.get(&"abc");
assert_eq!(Some("abc"), lru.mru());
source

pub fn pop_mru(&self) -> Option<(K, V)>

Pops the most recently used key, returning its value if the cache was non-empty.

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
assert_eq!(None, lru.pop_mru());
lru.push("abc", true);
lru.push("def", false);
assert_eq!(Some(("def", false)), lru.pop_mru());
assert_eq!(1, lru.len());
source

pub fn peek_mru(&self) -> Option<(K, V)>

Peeks the most recently used key. Returns its key and value.

There is no need for a get_mru, as getting the most recently used key does not alter order, so peek and get are equivalent.

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
assert_eq!(None, lru.peek_mru());
lru.push("abc", true);
lru.push("def", false);
assert_eq!(Some(("def", false)), lru.peek_mru());
assert_eq!(2, lru.len());
assert_eq!(Some("def"), lru.mru());
source

pub fn pop(&self, k: &K) -> Option<(K, V)>

Removes a key, returning the (key,value) pair if there was already something for this key.

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
lru.insert("abc", true);
lru.insert("def", true);
lru.insert("ghi", false);
assert_eq!(Some(("def", true)), lru.pop(&"def"));
assert!(lru.contains_key(&"abc"));
assert!(!lru.contains_key(&"def"));
assert!(lru.contains_key(&"ghi"));
source

pub fn remove(&self, k: &K) -> Option<V>

Removes a key, returning the value of the key if the key was previously in the map.

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
lru.insert("abc", true);
lru.insert("def", true);
lru.insert("ghi", false);
assert_eq!(Some(true), lru.remove(&"def"));
assert!(lru.contains_key(&"abc"));
assert!(!lru.contains_key(&"def"));
assert!(lru.contains_key(&"ghi"));
source

pub fn delete(&self, k: &K)

Delete a key, return nothing, just ensure key is gone.

§Examples
use hashlru::SyncCache;

let lru = SyncCache::new(10);
lru.insert("abc", true);
lru.insert("def", true);
lru.insert("ghi", false);
lru.delete(&"def");
assert!(lru.contains_key(&"abc"));
assert!(!lru.contains_key(&"def"));
assert!(lru.contains_key(&"ghi"));
source§

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

source

pub fn dump(&self) -> Dump<K, V>

Creates a dump of all keys and values, provided both have the Clone trait.

The dump has a complete copy of all data, with ownership.

§Examples
use hashlru::{SyncCache, Dump};

let cache = SyncCache::new(10);
cache.insert("x", 1);
cache.insert("y", 10);
cache.insert("z", 100);

let dump = cache.dump();
assert_eq!("Dump { capacity: 10, data: [(\"x\", 1), (\"y\", 10), (\"z\", 100)] }", format!("{:?}", &dump));
source

pub fn restore(&self, dump: &Dump<K, V>) -> usize

Restores data from a dump. Clears the data before importing the dump.

§Examples
use hashlru::{SyncCache, Dump};

let dump = Dump {
    capacity: 10,
    data: vec![("x", 1), ("y", 10), ("z", 100)],
};
let cache = SyncCache::new(2);
assert_eq!(2, cache.capacity());
cache.insert("a", 0);
cache.insert("b", 1);
cache.insert("c", 2);
assert_eq!(2, cache.len());
assert_eq!(3, cache.restore(&dump));
assert_eq!(10, cache.capacity());
assert_eq!("[sync] [x: 1, y: 10, z: 100]", format!("{}", &cache));
// another way to restore, taking ownership
let other_cache = SyncCache::from(dump);
source

pub fn import<I>(&mut self, iter: I) -> usize
where I: Iterator<Item = (K, V)>,

Import data from an iterator, typically the iterator returned by into_iter().

The data is not cleared before import, so values add to the existing ones.

§Examples
use hashlru::{Cache, SyncCache};

let mut cache1 = Cache::new(5);
cache1.insert("a", 0);
cache1.insert("b", 1);
cache1.insert("c", 2);
let mut cache2 = SyncCache::new(10);
cache2.insert("d", 3);
cache2.import(cache1.into_iter());
assert_eq!(4, cache2.len());
assert_eq!("[sync] [d: 3, a: 0, b: 1, c: 2]", format!("{}", &cache2));
source

pub fn to_map(&self) -> HashMap<K, V>

Exports all items as a map.

Does not preserve order.

§Examples
use hashlru::SyncCache;

let cache = SyncCache::new(10);
cache.insert("x", 1);
cache.insert("y", 10);
cache.insert("z", 100);

let map = cache.to_map();
assert_eq!(3, map.len());
assert_eq!(Some(&1), map.get(&"x"));
assert_eq!(Some(&10), map.get(&"y"));
assert_eq!(Some(&100), map.get(&"z"));
source

pub fn to_vec(&self) -> Vec<(K, V)>

Exports all items as a vec.

Preserves order, LRU has index 0.

§Examples
use hashlru::SyncCache;

let cache = SyncCache::new(10);
cache.insert("x", 1);
cache.insert("y", 10);
cache.insert("z", 100);

let vec = cache.to_vec();
assert_eq!(vec![("x", 1), ("y", 10), ("z", 100)], vec);

Trait Implementations§

source§

impl<K, V> Clone for SyncCache<K, V>
where K: Eq + Hash + Clone + Clone, V: Clone + Clone,

source§

fn clone(&self) -> SyncCache<K, V>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<K, V> Debug for SyncCache<K, V>
where K: Eq + Hash + Clone + Debug, V: Clone + Debug,

source§

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

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

impl<'de, K, V> Deserialize<'de> for SyncCache<K, V>
where K: 'de + Eq + Hash + Deserialize<'de> + Clone, V: 'de + Deserialize<'de> + Clone,

source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize the cache.

Cache and SyncCache and Dump all share the same representation so it is fine to (de)serialize from any of those.

use hashlru::SyncCache;

let export = "{\"capacity\":7,\"data\":[[1,10],[4,40],[2,20]]}";

let cache: SyncCache<usize, usize> = serde_json::from_str(&export).unwrap();

assert_eq!(3, cache.len());
assert_eq!(7, cache.capacity());
assert_eq!(Some(10), cache.get(&1));
assert_eq!(Some(40), cache.get(&4));
assert_eq!(Some(20), cache.get(&2));
assert_eq!(Some(1), cache.lru());
assert_eq!(Some(2), cache.mru());
assert_eq!("[sync] [1: 10, 4: 40, 2: 20]", format!("{}", &cache));
source§

impl<K, V> Display for SyncCache<K, V>
where K: Display + Hash + Eq + Clone, V: Display + Clone,

Pretty-print cache content.

Prints key-value pairs as if it was an ordered list. Which is, what it is, conceptually, even if implementation details differ and there is no array backing the store.

§Examples

use hashlru::SyncCache;

let a = SyncCache::new(900);
a.insert(1, "a");
a.insert(2, "b");
a.insert(3, "c");
assert_eq!("[sync] [1: a, 2: b, 3: c]", format!("{}", a));
for i in 10..1000 {
     a.insert(i, "more");
}
// If there are too many keys, just print a few.
assert_eq!("[sync] [100: more, 101: more, ..., 999: more]", format!("{}", a));
source§

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

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

impl<K, V> From<Cache<K, V>> for SyncCache<K, V>
where K: Hash + Eq + Clone, V: Clone,

Create a thread-safe cache from an ordinary cache.

§Examples

use hashlru::{Cache, SyncCache};

let a: Cache<String, String> = Cache::new(100);
let b = SyncCache::from(a);
assert_eq!(100, b.capacity());
source§

fn from(cache: Cache<K, V>) -> SyncCache<K, V>

Converts to this type from the input type.
source§

impl<K, V> From<Dump<K, V>> for SyncCache<K, V>
where K: Hash + Eq + Clone, V: Clone,

source§

fn from(dump: Dump<K, V>) -> SyncCache<K, V>

Converts to this type from the input type.
source§

impl<K, V> From<HashMap<K, V>> for SyncCache<K, V>
where K: Hash + Eq + Clone, V: Clone,

source§

fn from(map: HashMap<K, V>) -> SyncCache<K, V>

Converts to this type from the input type.
source§

impl<K, V> From<SyncCache<K, V>> for Cache<K, V>
where K: Hash + Eq + Clone, V: Clone,

Create an ordinary cache from a thread-safe cache.

This is possibly slow as it is O(n) since it clones the cache.

§Examples

use hashlru::{Cache, SyncCache};

let a: SyncCache<String, String> = SyncCache::new(100);
let b = Cache::from(a);
assert_eq!(100, b.capacity());
source§

fn from(cache: SyncCache<K, V>) -> Cache<K, V>

Converts to this type from the input type.
source§

impl<K, V> From<Vec<(K, V)>> for SyncCache<K, V>
where K: Hash + Eq + Clone, V: Clone,

source§

fn from(vec: Vec<(K, V)>) -> SyncCache<K, V>

Converts to this type from the input type.
source§

impl<K, V> FromIterator<(K, V)> for SyncCache<K, V>
where K: Eq + Hash + Clone, V: Clone,

source§

fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self

Creates a new cache from an iterator.

With this, you can use collect() to build a cache.

§Examples
use hashlru::SyncCache;
use std::collections::HashMap;

let mut src: HashMap<usize, &str> = HashMap::new();
src.insert(1, "two");
src.insert(2, "four");
src.insert(3, "eight");

let cache = src.into_iter().filter(|x| x.0 != 2).collect::<SyncCache<usize, &str>>();
assert_eq!(2, cache.len());
assert_eq!(Some("two"), cache.get(&1));
assert_eq!(Some("eight"), cache.get(&3));
source§

impl<K, V> Serialize for SyncCache<K, V>
where K: Serialize + Eq + Hash + Clone, V: Serialize + Clone,

source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize the sync cache.

This is possibly long, and requires data to support Clone. Internally, just does a Dump and serializes it.

use hashlru::SyncCache;
use serde_json::json;

let cache = SyncCache::new(10);

cache.insert(1, 10);
cache.insert(2, 20);

let export = json!(&cache).to_string();

assert_eq!("{\"capacity\":10,\"data\":[[1,10],[2,20]]}", export);

Auto Trait Implementations§

§

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

§

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

§

impl<K, V> Send for SyncCache<K, V>
where K: Sync + Send, V: Sync + Send,

§

impl<K, V> Sync for SyncCache<K, V>
where K: Sync + Send, V: Sync + Send,

§

impl<K, V> Unpin for SyncCache<K, V>

§

impl<K, V> UnwindSafe for SyncCache<K, V>

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> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

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

§

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>,

§

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.
source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,