use super::*;
type TestMap = LRUMap<&'static str, i32, 4>;
fn items<K, T, const N: usize>(map: &mut LRUMap<K, T, N>) -> Vec<(K, T)>
where
K: Hash + Eq + Clone,
T: Clone
{
let mut v = Vec::new();
for (k, val) in map.iter() {
v.push((k.clone(), val.clone()))
}
v
}
#[inline]
fn get_untouch<T, const N: usize>(cache: &Cache<T, N>, idx: u16) -> &T {
&cache.entries[idx as usize].val
}
fn check_keys<K, T, const N: usize>(map: &LRUMap<K, T, N>) -> bool
where
K: Hash + Eq + Clone,
T: Clone
{
for (key, idx) in map.indices.iter() {
if get_untouch(&map.cache, *idx).0 != *key {
return false
}
}
return true
}
#[test]
fn empty() {
let cache = TestMap::default();
assert!(cache.len() == 0);
}
#[test]
fn put() {
let mut cache = TestMap::default();
assert_eq!(cache.put("1", 1), None);
assert_eq!(cache.len(), 1);
assert_eq!(cache.put("2", 2), None);
assert_eq!(cache.len(), 2);
assert_eq!(cache.put("3", 3), None);
assert_eq!(cache.len(), 3);
assert_eq!(cache.put("4", 4), None);
assert_eq!(cache.len(), 4);
assert_eq!(
items(&mut cache),
[("4", 4), ("3", 3), ("2", 2), ("1", 1)],
"Ordered from most- to least_recent."
);
assert!(check_keys(&cache), "check keys");
assert_eq!(cache.put("5", 5), None);
assert_eq!(cache.len(), 4);
assert_eq!(
items(&mut cache),
[("5", 5), ("4", 4), ("3", 3), ("2", 2)],
"Least-recently-used item evicted."
);
assert_eq!(cache.put("6", 6), None);
assert_eq!(cache.put("7", 7), None);
assert_eq!(cache.put("8", 8), None);
assert_eq!(cache.put("9", 9), None);
assert_eq!(
items(&mut cache),
[("9", 9), ("8", 8), ("7", 7), ("6", 6)],
"Least-recently-used item evicted."
);
assert_eq!(cache.put("7", 14), Some(7));
assert_eq!(
items(&mut cache),
[("7", 14), ("9", 9), ("8", 8), ("6", 6)],
"Least-recently-used item evicted."
);
}
#[test]
fn cache_hit() {
let mut cache = TestMap::default();
assert_eq!(cache.put("1", 1), None);
assert_eq!(cache.put("2", 2), None);
assert_eq!(cache.put("3", 3), None);
assert_eq!(cache.put("4", 4), None);
assert_eq!(cache.len(), 4);
assert_eq!(
items(&mut cache),
[("4", 4), ("3", 3), ("2", 2), ("1", 1)],
"Ordered from most- to least-recent."
);
assert_eq!(cache.get(&"1"), Some(&1));
assert_eq!(
items(&mut cache),
[("1", 1), ("4", 4), ("3", 3), ("2", 2)],
"Matching item moved to front."
);
cache.remove_one(&"2");
assert_eq!(
items(&mut cache),
[("1", 1), ("4", 4), ("3", 3)],
"Removing one item."
);
cache.touch(|k| *k == "3");
assert_eq!(
items(&mut cache),
[("3", 3), ("1", 1), ("4", 4)],
"Touching one item."
);
let val = cache.get_mut(&"1").unwrap();
*val = 5;
assert_eq!(
items(&mut cache),
[("1", 5), ("3", 3), ("4", 4)],
"Touching one item."
);
}
#[test]
fn clear() {
let mut cache = TestMap::default();
cache.put("1", 1);
cache.clear();
assert_eq!(items(&mut cache), [], "all items evicted");
cache.put("1", 1);
cache.put("2", 2);
cache.put("3", 3);
cache.put("4", 4);
assert_eq!(
items(&mut cache),
[("4", 4), ("3", 3), ("2", 2), ("1", 1)]);
cache.clear();
assert_eq!(items(&mut cache), [], "all items evicted again");
}