pub struct SyncCache<K, V>{ /* 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>
impl<K, V> SyncCache<K, V>
sourcepub fn len(&self) -> usize
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);
sourcepub fn capacity(&self) -> usize
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);
sourcepub fn is_empty(&self) -> bool
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());
sourcepub fn is_full(&self) -> bool
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());
sourcepub fn clear(&self)
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());
sourcepub fn new(capacity: usize) -> SyncCache<K, V>
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);
sourcepub fn resize(&self, capacity: usize) -> usize
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());
sourcepub fn insert(&self, k: K, v: V) -> Option<V>
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));
sourcepub fn push(&self, k: K, v: V) -> Option<(K, V)>
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);
sourcepub fn get(&self, k: &K) -> Option<V>
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);
sourcepub fn bump(&self, k: &K)
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());
sourcepub fn get_key_value(&self, k: &K) -> Option<(K, V)>
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));
sourcepub fn peek(&self, k: &K) -> Option<V>
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);
sourcepub fn peek_key_value(&self, k: &K) -> Option<(K, V)>
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));
sourcepub fn contains_key(&self, k: &K) -> bool
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));
sourcepub fn lru(&self) -> Option<K>
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());
sourcepub fn pop_lru(&self) -> Option<(K, V)>
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());
sourcepub fn get_lru(&self) -> Option<(K, V)>
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());
sourcepub fn peek_lru(&self) -> Option<(K, V)>
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());
sourcepub fn mru(&self) -> Option<K>
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());
sourcepub fn pop_mru(&self) -> Option<(K, V)>
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());
sourcepub fn peek_mru(&self) -> Option<(K, V)>
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());
sourcepub fn pop(&self, k: &K) -> Option<(K, V)>
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"));
sourcepub fn remove(&self, k: &K) -> Option<V>
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"));
sourcepub fn delete(&self, k: &K)
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>
impl<K, V> SyncCache<K, V>
sourcepub fn dump(&self) -> Dump<K, V>
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));
sourcepub fn restore(&self, dump: &Dump<K, V>) -> usize
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);
sourcepub fn import<I>(&mut self, iter: I) -> usize
pub fn import<I>(&mut self, iter: I) -> usize
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));
sourcepub fn to_map(&self) -> HashMap<K, V>
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"));
sourcepub fn to_vec(&self) -> Vec<(K, V)>
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<'de, K, V> Deserialize<'de> for SyncCache<K, V>
impl<'de, K, V> Deserialize<'de> for SyncCache<K, V>
source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
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>
impl<K, V> Display for SyncCache<K, V>
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§impl<K, V> From<Cache<K, V>> for SyncCache<K, V>
impl<K, V> From<Cache<K, V>> for SyncCache<K, V>
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§impl<K, V> From<SyncCache<K, V>> for Cache<K, V>
impl<K, V> From<SyncCache<K, V>> for Cache<K, V>
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§impl<K, V> FromIterator<(K, V)> for SyncCache<K, V>
impl<K, V> FromIterator<(K, V)> for SyncCache<K, V>
source§fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self
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>
impl<K, V> Serialize for SyncCache<K, V>
source§fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>where
S: Serializer,
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);