1use std::{
19 collections::HashMap,
20 hash::Hash,
21 sync::{Arc, Weak},
22};
23
24use parking_lot::Mutex;
25
26#[derive(Default)]
27pub struct LruQueue<K: Eq + Hash + Clone, V> {
45 data: LruData<K, V>,
46 queue: LruList<K>,
47}
48
49type LruData<K, V> = HashMap<K, (Arc<Mutex<LruNode<K>>>, V)>;
51
52#[derive(Default)]
53struct LruList<K> {
55 head: Link<K>,
56 tail: Link<K>,
57}
58
59struct LruNode<K> {
61 key: K,
62 prev: Link<K>,
63 next: Link<K>,
64}
65
66type Link<K> = Option<Weak<Mutex<LruNode<K>>>>;
69
70impl<K: Eq + Hash + Clone, V> LruQueue<K, V> {
71 pub fn new() -> Self {
72 Self {
73 data: HashMap::new(),
74 queue: LruList {
75 head: None,
76 tail: None,
77 },
78 }
79 }
80
81 pub fn get(&mut self, key: &K) -> Option<&V> {
84 if let Some(value) = self.remove(key) {
85 self.put(key.clone(), value);
86 }
87 self.data.get(key).map(|(_, value)| value)
88 }
89
90 pub fn peek(&self, key: &K) -> Option<&V> {
93 self.data.get(key).map(|(_, value)| value)
94 }
95
96 pub fn contains_key(&self, key: &K) -> bool {
99 self.data.contains_key(key)
100 }
101
102 pub fn put(&mut self, key: K, value: V) -> Option<V> {
105 let old_value = self.remove(&key);
106
107 let node = Arc::new(Mutex::new(LruNode {
108 key: key.clone(),
109 prev: None,
110 next: None,
111 }));
112
113 match self.queue.head {
114 Some(ref old_head) => {
116 old_head
117 .upgrade()
118 .expect("value has been unexpectedly dropped")
119 .lock()
120 .prev = Some(Arc::downgrade(&node));
121 node.lock().next = Some(Weak::clone(old_head));
122 self.queue.head = Some(Arc::downgrade(&node));
123 }
124 _ => {
126 self.queue.head = Some(Arc::downgrade(&node));
127 self.queue.tail = Some(Arc::downgrade(&node));
128 }
129 }
130
131 self.data.insert(key, (node, value));
132
133 old_value
134 }
135
136 pub fn pop(&mut self) -> Option<(K, V)> {
139 let key_to_remove = self.queue.tail.as_ref().map(|n| {
140 n.upgrade()
141 .expect("value has been unexpectedly dropped")
142 .lock()
143 .key
144 .clone()
145 });
146 if let Some(k) = key_to_remove {
147 let value = self.remove(&k).unwrap(); Some((k, value))
149 } else {
150 None
151 }
152 }
153
154 pub fn remove(&mut self, key: &K) -> Option<V> {
156 if let Some((old_node, old_value)) = self.data.remove(key) {
157 let LruNode { key: _, prev, next } = &*old_node.lock();
158 match (prev, next) {
159 (None, None) => {
161 self.queue.head = None;
162 self.queue.tail = None;
163 }
164 (None, Some(n)) => {
166 let n_strong =
167 n.upgrade().expect("value has been unexpectedly dropped");
168 n_strong.lock().prev = None;
169 self.queue.head = Some(Weak::clone(n));
170 }
171 (Some(p), None) => {
173 let p_strong =
174 p.upgrade().expect("value has been unexpectedly dropped");
175 p_strong.lock().next = None;
176 self.queue.tail = Some(Weak::clone(p));
177 }
178 (Some(p), Some(n)) => {
180 let n_strong =
181 n.upgrade().expect("value has been unexpectedly dropped");
182 let p_strong =
183 p.upgrade().expect("value has been unexpectedly dropped");
184 n_strong.lock().prev = Some(Weak::clone(p));
185 p_strong.lock().next = Some(Weak::clone(n));
186 }
187 };
188 Some(old_value)
189 } else {
190 None
191 }
192 }
193
194 pub fn len(&self) -> usize {
196 self.data.len()
197 }
198
199 pub fn is_empty(&self) -> bool {
201 self.data.is_empty()
202 }
203
204 pub fn clear(&mut self) {
206 self.queue.head = None;
207 self.queue.tail = None;
208 self.data.clear();
209 }
210
211 pub fn list_entries(&self) -> HashMap<&K, &V> {
213 self.data.iter().map(|(k, (_, v))| (k, v)).collect()
214 }
215}
216
217#[cfg(test)]
218mod tests {
219 use std::collections::HashMap;
220
221 use rand::seq::IndexedRandom;
222
223 use crate::cache::lru_queue::LruQueue;
224
225 #[test]
226 fn test_get() {
227 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
228
229 assert_eq!(lru_queue.get(&1), None);
231
232 lru_queue.put(1, 10);
234 assert_eq!(lru_queue.get(&1), Some(&10));
235 assert_eq!(lru_queue.get(&1), Some(&10));
236
237 lru_queue.remove(&1);
239 assert_eq!(lru_queue.get(&1), None);
240 }
241
242 #[test]
243 fn test_peek() {
244 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
245
246 assert_eq!(lru_queue.peek(&1), None);
248
249 lru_queue.put(1, 10);
251 assert_eq!(lru_queue.peek(&1), Some(&10));
252 assert_eq!(lru_queue.peek(&1), Some(&10));
253
254 lru_queue.remove(&1);
256 assert_eq!(lru_queue.peek(&1), None);
257 }
258
259 #[test]
260 fn test_put() {
261 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
262
263 assert_eq!(lru_queue.put(1, 10), None);
265
266 assert_eq!(lru_queue.put(1, 11), Some(10));
268 assert_eq!(lru_queue.put(1, 12), Some(11));
269 assert_eq!(lru_queue.put(1, 13), Some(12));
270 }
271
272 #[test]
273 fn test_remove() {
274 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
275
276 assert_eq!(lru_queue.remove(&1), None);
278
279 lru_queue.put(1, 10);
281 assert_eq!(lru_queue.remove(&1), Some(10));
282
283 assert_eq!(lru_queue.remove(&1), None);
285 }
286
287 #[test]
288 fn test_contains_key() {
289 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
290
291 assert!(!lru_queue.contains_key(&1));
293
294 lru_queue.put(1, 10);
296 assert!(lru_queue.contains_key(&1));
297
298 lru_queue.remove(&1);
300 assert!(!lru_queue.contains_key(&1));
301 }
302
303 #[test]
304 fn test_len() {
305 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
306
307 assert_eq!(lru_queue.len(), 0);
309
310 lru_queue.put(1, 10);
312 assert_eq!(lru_queue.len(), 1);
313 lru_queue.put(2, 20);
314 assert_eq!(lru_queue.len(), 2);
315 lru_queue.put(3, 30);
316 assert_eq!(lru_queue.len(), 3);
317 lru_queue.put(1, 11);
318 lru_queue.put(3, 31);
319 assert_eq!(lru_queue.len(), 3);
320
321 lru_queue.remove(&1);
323 assert_eq!(lru_queue.len(), 2);
324 lru_queue.remove(&1);
325 assert_eq!(lru_queue.len(), 2);
326 lru_queue.remove(&4);
327 assert_eq!(lru_queue.len(), 2);
328 lru_queue.remove(&3);
329 assert_eq!(lru_queue.len(), 1);
330 lru_queue.remove(&2);
331 assert_eq!(lru_queue.len(), 0);
332 lru_queue.remove(&2);
333 assert_eq!(lru_queue.len(), 0);
334
335 lru_queue.put(1, 10);
337 lru_queue.put(2, 20);
338 lru_queue.put(3, 30);
339 assert_eq!(lru_queue.len(), 3);
340 lru_queue.clear();
341 assert_eq!(lru_queue.len(), 0);
342 }
343
344 #[test]
345 fn test_is_empty() {
346 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
347
348 assert!(lru_queue.is_empty());
350
351 lru_queue.put(1, 10);
353 assert!(!lru_queue.is_empty());
354 lru_queue.put(2, 20);
355 assert!(!lru_queue.is_empty());
356
357 lru_queue.remove(&1);
359 assert!(!lru_queue.is_empty());
360 lru_queue.remove(&1);
361 assert!(!lru_queue.is_empty());
362 lru_queue.remove(&2);
363 assert!(lru_queue.is_empty());
364
365 lru_queue.put(1, 10);
367 lru_queue.put(2, 20);
368 lru_queue.put(3, 30);
369 assert!(!lru_queue.is_empty());
370 lru_queue.clear();
371 assert!(lru_queue.is_empty());
372 }
373
374 #[test]
375 fn test_clear() {
376 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
377
378 lru_queue.clear();
380
381 lru_queue.put(1, 10);
383 lru_queue.put(2, 20);
384 lru_queue.put(3, 30);
385 assert_eq!(lru_queue.get(&1), Some(&10));
386 assert_eq!(lru_queue.get(&2), Some(&20));
387 assert_eq!(lru_queue.get(&3), Some(&30));
388 lru_queue.clear();
389 assert_eq!(lru_queue.get(&1), None);
390 assert_eq!(lru_queue.get(&2), None);
391 assert_eq!(lru_queue.get(&3), None);
392 assert_eq!(lru_queue.len(), 0);
393 }
394
395 #[test]
396 fn test_pop() {
397 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
398
399 assert_eq!(lru_queue.pop(), None);
401
402 lru_queue.put(1, 10);
404 lru_queue.put(2, 20);
405 lru_queue.put(3, 30);
406 assert_eq!(lru_queue.pop(), Some((1, 10)));
407 assert_eq!(lru_queue.pop(), Some((2, 20)));
408 assert_eq!(lru_queue.pop(), Some((3, 30)));
409 assert_eq!(lru_queue.pop(), None);
410
411 lru_queue.put(1, 10);
413 lru_queue.put(2, 20);
414 lru_queue.put(3, 30);
415 lru_queue.get(&2);
416 assert_eq!(lru_queue.pop(), Some((1, 10)));
417 assert_eq!(lru_queue.pop(), Some((3, 30)));
418 assert_eq!(lru_queue.pop(), Some((2, 20)));
419 assert_eq!(lru_queue.pop(), None);
420
421 lru_queue.put(1, 10);
423 lru_queue.put(2, 20);
424 lru_queue.put(3, 30);
425 lru_queue.get(&2);
426 lru_queue.get(&3);
427 lru_queue.get(&1);
428 assert_eq!(lru_queue.pop(), Some((2, 20)));
429 assert_eq!(lru_queue.pop(), Some((3, 30)));
430 assert_eq!(lru_queue.pop(), Some((1, 10)));
431 assert_eq!(lru_queue.pop(), None);
432
433 lru_queue.put(1, 10);
435 lru_queue.put(2, 20);
436 lru_queue.put(3, 30);
437 lru_queue.peek(&2);
438 assert_eq!(lru_queue.pop(), Some((1, 10)));
439 assert_eq!(lru_queue.pop(), Some((2, 20)));
440 assert_eq!(lru_queue.pop(), Some((3, 30)));
441 assert_eq!(lru_queue.pop(), None);
442
443 lru_queue.put(1, 10);
445 lru_queue.put(2, 20);
446 lru_queue.put(3, 30);
447 lru_queue.contains_key(&2);
448 assert_eq!(lru_queue.pop(), Some((1, 10)));
449 assert_eq!(lru_queue.pop(), Some((2, 20)));
450 assert_eq!(lru_queue.pop(), Some((3, 30)));
451 assert_eq!(lru_queue.pop(), None);
452
453 lru_queue.put(1, 10);
455 lru_queue.put(2, 20);
456 lru_queue.put(3, 30);
457 lru_queue.put(2, 21);
458 assert_eq!(lru_queue.pop(), Some((1, 10)));
459 assert_eq!(lru_queue.pop(), Some((3, 30)));
460 assert_eq!(lru_queue.pop(), Some((2, 21)));
461 assert_eq!(lru_queue.pop(), None);
462
463 lru_queue.put(1, 10);
465 lru_queue.put(2, 20);
466 lru_queue.put(3, 30);
467 lru_queue.put(2, 21);
468 lru_queue.put(3, 31);
469 lru_queue.put(1, 11);
470 assert_eq!(lru_queue.pop(), Some((2, 21)));
471 assert_eq!(lru_queue.pop(), Some((3, 31)));
472 assert_eq!(lru_queue.pop(), Some((1, 11)));
473 assert_eq!(lru_queue.pop(), None);
474
475 lru_queue.put(1, 10);
477 lru_queue.put(2, 20);
478 lru_queue.put(3, 30);
479 lru_queue.remove(&2);
480 assert_eq!(lru_queue.pop(), Some((1, 10)));
481 assert_eq!(lru_queue.pop(), Some((3, 30)));
482 assert_eq!(lru_queue.pop(), None);
483
484 lru_queue.put(1, 10);
486 lru_queue.put(2, 20);
487 lru_queue.put(3, 30);
488 lru_queue.remove(&1);
489 assert_eq!(lru_queue.pop(), Some((2, 20)));
490 assert_eq!(lru_queue.pop(), Some((3, 30)));
491 assert_eq!(lru_queue.pop(), None);
492
493 lru_queue.put(1, 10);
495 lru_queue.put(2, 20);
496 lru_queue.put(3, 30);
497 lru_queue.remove(&3);
498 assert_eq!(lru_queue.pop(), Some((1, 10)));
499 assert_eq!(lru_queue.pop(), Some((2, 20)));
500 assert_eq!(lru_queue.pop(), None);
501 }
502
503 #[test]
504 fn test_fuzzy() {
506 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
507 let mut map: HashMap<i32, i32> = HashMap::new();
508 let max_keys = 1_000;
509 let methods = ["get", "put", "remove", "pop", "contains", "len"];
510 let mut rng = rand::rng();
511
512 for i in 0..1_000_000 {
513 match *methods.choose(&mut rng).unwrap() {
514 "get" => {
515 assert_eq!(lru_queue.get(&(i % max_keys)), map.get(&(i % max_keys)))
516 }
517 "put" => assert_eq!(
518 lru_queue.put(i % max_keys, i),
519 map.insert(i % max_keys, i)
520 ),
521 "remove" => assert_eq!(
522 lru_queue.remove(&(i % max_keys)),
523 map.remove(&(i % max_keys))
524 ),
525 "pop" => {
526 let removed = lru_queue.pop();
527 if let Some((k, v)) = removed {
528 assert_eq!(Some(v), map.remove(&k))
529 }
530 }
531 "contains" => {
532 assert_eq!(
533 lru_queue.contains_key(&(i % max_keys)),
534 map.contains_key(&(i % max_keys))
535 )
536 }
537 "len" => assert_eq!(lru_queue.len(), map.len()),
538 _ => unreachable!(),
539 }
540 }
541 }
542}