mirror of https://github.com/dswd/zvault
54 lines
1.3 KiB
Rust
54 lines
1.3 KiB
Rust
|
|
||
|
use std::hash::Hash;
|
||
|
use std::collections::HashMap;
|
||
|
|
||
|
pub struct LruCache<K, V> {
|
||
|
items: HashMap<K, (V, u64)>,
|
||
|
min_size: usize,
|
||
|
max_size: usize,
|
||
|
next: u64
|
||
|
}
|
||
|
|
||
|
|
||
|
impl<K: Eq+Hash, V> LruCache<K, V> {
|
||
|
#[inline]
|
||
|
pub fn new(min_size: usize, max_size: usize) -> Self {
|
||
|
LruCache {
|
||
|
items: HashMap::default(),
|
||
|
min_size: min_size,
|
||
|
max_size: max_size,
|
||
|
next: 0
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[inline]
|
||
|
pub fn put(&mut self, key: K, value: V) {
|
||
|
self.items.insert(key, (value, self.next));
|
||
|
self.next += 1;
|
||
|
if self.items.len() > self.max_size {
|
||
|
self.shrink()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[inline]
|
||
|
pub fn get(&mut self, key: &K) -> Option<&V> {
|
||
|
if let Some(&mut (ref item, ref mut n)) = self.items.get_mut(key) {
|
||
|
*n = self.next;
|
||
|
self.next += 1;
|
||
|
Some(item)
|
||
|
} else {
|
||
|
None
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[inline]
|
||
|
fn shrink(&mut self) {
|
||
|
let mut tags: Vec<u64> = self.items.values().map(|&(_, n)| n).collect();
|
||
|
tags.sort();
|
||
|
let bar = tags[tags.len()-self.min_size];
|
||
|
let mut new = HashMap::with_capacity(self.min_size);
|
||
|
new.extend(self.items.drain().filter(|&(_,(_, n))| n>=bar));
|
||
|
self.items = new;
|
||
|
}
|
||
|
}
|