Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ where
let key = self.next_unexpired(now)?;
self.list.push_back(key);
let key = self.list.back()?;
let mut value = self.map.get_mut(&key)?;
let mut value = self.map.get_mut(key)?;
value.1 = now;

unsafe {
Expand Down Expand Up @@ -225,7 +225,7 @@ where
let now = Instant::now();
self.next_unexpired(now)?;
let key = &self.list[self.item_index];
let value = self.map.get(&key)?;
let value = self.map.get(key)?;

unsafe {
let key = std::mem::transmute::<&Key, &'a Key>(key);
Expand Down
47 changes: 46 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
#[cfg(feature = "sn_fake_clock")]
use sn_fake_clock::FakeClock as Instant;
use std::borrow::Borrow;
use std::collections::{BTreeMap, VecDeque};
use std::collections::{btree_map, BTreeMap, VecDeque};
Comment thread
dirvine marked this conversation as resolved.
Outdated
use std::time::Duration;
#[cfg(not(feature = "sn_fake_clock"))]
use std::time::Instant;
Expand Down Expand Up @@ -325,6 +325,32 @@ where
PeekIter::new(&self.map, &self.list, self.time_to_live)
}

/// Retains only the elements specified by the predicate. Also removes expired elements
/// before passing them to the predicate.
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut((&'_ Key, &'_ Value)) -> bool,
{
let (map, list) = (&mut self.map, &mut self.list);

let now = Instant::now();
let ttl = self.time_to_live;

list.retain(|key| match map.entry(key.clone()) {
btree_map::Entry::Occupied(entry) => {
if matches!(ttl, Some(ttl) if entry.get().1 + ttl < now)
|| !f((key, &entry.get().0))
{
let _ = entry.remove();
false
} else {
true
}
}
btree_map::Entry::Vacant(_) => false,
});
}

// Move `key` in the ordered list to the last
fn update_key<Q: ?Sized>(list: &mut VecDeque<Key>, key: &Q)
where
Expand Down Expand Up @@ -753,6 +779,25 @@ mod test {
}
}

mod retain {
use super::*;

#[test]
fn it_removes_all_invalid_entries() {
let mut lru_cache = LruCache::<usize, usize>::with_capacity(4);
let _ = lru_cache.insert(2, 2);
let _ = lru_cache.insert(0, 0);
let _ = lru_cache.insert(3, 3);
let _ = lru_cache.insert(1, 1);

lru_cache.retain(|(_, &value)| value > 1);

let cached = lru_cache.peek_iter().collect::<Vec<_>>();

assert_eq!(cached, vec![(&3, &3), (&2, &2)]);
}
}

mod notify_iter {
use super::*;

Expand Down