1use core::hash::Hash;
5use std::collections::{HashMap, VecDeque};
6use std::num::NonZeroUsize;
7use std::sync::Mutex;
8
9use crate::cache::Cache;
10use crate::error::CacheError;
11use crate::util::MutexExt;
12
13pub struct LruCache<K, V> {
40 capacity: NonZeroUsize,
41 inner: Mutex<Inner<K, V>>,
42}
43
44struct Inner<K, V> {
45 map: HashMap<K, V>,
47 order: VecDeque<K>,
49}
50
51impl<K, V> LruCache<K, V>
52where
53 K: Eq + Hash + Clone,
54 V: Clone,
55{
56 pub fn new(capacity: usize) -> Result<Self, CacheError> {
68 let cap = NonZeroUsize::new(capacity).ok_or(CacheError::InvalidCapacity)?;
69 Ok(Self::with_capacity(cap))
70 }
71
72 pub fn with_capacity(capacity: NonZeroUsize) -> Self {
84 let cap = capacity.get();
85 Self {
86 capacity,
87 inner: Mutex::new(Inner {
88 map: HashMap::with_capacity(cap),
89 order: VecDeque::with_capacity(cap),
90 }),
91 }
92 }
93}
94
95impl<K, V> Cache<K, V> for LruCache<K, V>
96where
97 K: Eq + Hash + Clone,
98 V: Clone,
99{
100 fn get(&self, key: &K) -> Option<V> {
101 let mut inner = self.inner.lock_recover();
102 let value = inner.map.get(key)?.clone();
103 promote(&mut inner.order, key);
104 Some(value)
105 }
106
107 fn insert(&self, key: K, value: V) -> Option<V> {
108 let mut inner = self.inner.lock_recover();
109 let old = inner.map.insert(key.clone(), value);
110 if old.is_some() {
111 promote(&mut inner.order, &key);
112 } else {
113 inner.order.push_front(key);
114 while inner.order.len() > self.capacity.get() {
115 if let Some(evicted) = inner.order.pop_back() {
116 let _ = inner.map.remove(&evicted);
117 }
118 }
119 }
120 old
121 }
122
123 fn remove(&self, key: &K) -> Option<V> {
124 let mut inner = self.inner.lock_recover();
125 let value = inner.map.remove(key)?;
126 if let Some(pos) = inner.order.iter().position(|k| k == key) {
127 let _ = inner.order.remove(pos);
128 }
129 Some(value)
130 }
131
132 fn contains_key(&self, key: &K) -> bool {
133 self.inner.lock_recover().map.contains_key(key)
134 }
135
136 fn len(&self) -> usize {
137 self.inner.lock_recover().map.len()
138 }
139
140 fn clear(&self) {
141 let mut inner = self.inner.lock_recover();
142 inner.map.clear();
143 inner.order.clear();
144 }
145
146 fn capacity(&self) -> usize {
147 self.capacity.get()
148 }
149}
150
151fn promote<K: Eq>(order: &mut VecDeque<K>, key: &K) {
153 if let Some(pos) = order.iter().position(|k| k == key) {
154 if let Some(k) = order.remove(pos) {
155 order.push_front(k);
156 }
157 }
158}