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 pub fn keys(&self) -> impl Iterator<Item = &K> {
219 self.data.keys()
220 }
221}
222
223#[cfg(test)]
224mod tests {
225 use std::collections::HashMap;
226
227 use rand::seq::IndexedRandom;
228
229 use crate::cache::lru_queue::LruQueue;
230
231 #[test]
232 fn test_get() {
233 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
234
235 assert_eq!(lru_queue.get(&1), None);
237
238 lru_queue.put(1, 10);
240 assert_eq!(lru_queue.get(&1), Some(&10));
241 assert_eq!(lru_queue.get(&1), Some(&10));
242
243 lru_queue.remove(&1);
245 assert_eq!(lru_queue.get(&1), None);
246 }
247
248 #[test]
249 fn test_peek() {
250 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
251
252 assert_eq!(lru_queue.peek(&1), None);
254
255 lru_queue.put(1, 10);
257 assert_eq!(lru_queue.peek(&1), Some(&10));
258 assert_eq!(lru_queue.peek(&1), Some(&10));
259
260 lru_queue.remove(&1);
262 assert_eq!(lru_queue.peek(&1), None);
263 }
264
265 #[test]
266 fn test_put() {
267 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
268
269 assert_eq!(lru_queue.put(1, 10), None);
271
272 assert_eq!(lru_queue.put(1, 11), Some(10));
274 assert_eq!(lru_queue.put(1, 12), Some(11));
275 assert_eq!(lru_queue.put(1, 13), Some(12));
276 }
277
278 #[test]
279 fn test_remove() {
280 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
281
282 assert_eq!(lru_queue.remove(&1), None);
284
285 lru_queue.put(1, 10);
287 assert_eq!(lru_queue.remove(&1), Some(10));
288
289 assert_eq!(lru_queue.remove(&1), None);
291 }
292
293 #[test]
294 fn test_contains_key() {
295 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
296
297 assert!(!lru_queue.contains_key(&1));
299
300 lru_queue.put(1, 10);
302 assert!(lru_queue.contains_key(&1));
303
304 lru_queue.remove(&1);
306 assert!(!lru_queue.contains_key(&1));
307 }
308
309 #[test]
310 fn test_len() {
311 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
312
313 assert_eq!(lru_queue.len(), 0);
315
316 lru_queue.put(1, 10);
318 assert_eq!(lru_queue.len(), 1);
319 lru_queue.put(2, 20);
320 assert_eq!(lru_queue.len(), 2);
321 lru_queue.put(3, 30);
322 assert_eq!(lru_queue.len(), 3);
323 lru_queue.put(1, 11);
324 lru_queue.put(3, 31);
325 assert_eq!(lru_queue.len(), 3);
326
327 lru_queue.remove(&1);
329 assert_eq!(lru_queue.len(), 2);
330 lru_queue.remove(&1);
331 assert_eq!(lru_queue.len(), 2);
332 lru_queue.remove(&4);
333 assert_eq!(lru_queue.len(), 2);
334 lru_queue.remove(&3);
335 assert_eq!(lru_queue.len(), 1);
336 lru_queue.remove(&2);
337 assert_eq!(lru_queue.len(), 0);
338 lru_queue.remove(&2);
339 assert_eq!(lru_queue.len(), 0);
340
341 lru_queue.put(1, 10);
343 lru_queue.put(2, 20);
344 lru_queue.put(3, 30);
345 assert_eq!(lru_queue.len(), 3);
346 lru_queue.clear();
347 assert_eq!(lru_queue.len(), 0);
348 }
349
350 #[test]
351 fn test_is_empty() {
352 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
353
354 assert!(lru_queue.is_empty());
356
357 lru_queue.put(1, 10);
359 assert!(!lru_queue.is_empty());
360 lru_queue.put(2, 20);
361 assert!(!lru_queue.is_empty());
362
363 lru_queue.remove(&1);
365 assert!(!lru_queue.is_empty());
366 lru_queue.remove(&1);
367 assert!(!lru_queue.is_empty());
368 lru_queue.remove(&2);
369 assert!(lru_queue.is_empty());
370
371 lru_queue.put(1, 10);
373 lru_queue.put(2, 20);
374 lru_queue.put(3, 30);
375 assert!(!lru_queue.is_empty());
376 lru_queue.clear();
377 assert!(lru_queue.is_empty());
378 }
379
380 #[test]
381 fn test_clear() {
382 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
383
384 lru_queue.clear();
386
387 lru_queue.put(1, 10);
389 lru_queue.put(2, 20);
390 lru_queue.put(3, 30);
391 assert_eq!(lru_queue.get(&1), Some(&10));
392 assert_eq!(lru_queue.get(&2), Some(&20));
393 assert_eq!(lru_queue.get(&3), Some(&30));
394 lru_queue.clear();
395 assert_eq!(lru_queue.get(&1), None);
396 assert_eq!(lru_queue.get(&2), None);
397 assert_eq!(lru_queue.get(&3), None);
398 assert_eq!(lru_queue.len(), 0);
399 }
400
401 #[test]
402 fn test_pop() {
403 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
404
405 assert_eq!(lru_queue.pop(), None);
407
408 lru_queue.put(1, 10);
410 lru_queue.put(2, 20);
411 lru_queue.put(3, 30);
412 assert_eq!(lru_queue.pop(), Some((1, 10)));
413 assert_eq!(lru_queue.pop(), Some((2, 20)));
414 assert_eq!(lru_queue.pop(), Some((3, 30)));
415 assert_eq!(lru_queue.pop(), None);
416
417 lru_queue.put(1, 10);
419 lru_queue.put(2, 20);
420 lru_queue.put(3, 30);
421 lru_queue.get(&2);
422 assert_eq!(lru_queue.pop(), Some((1, 10)));
423 assert_eq!(lru_queue.pop(), Some((3, 30)));
424 assert_eq!(lru_queue.pop(), Some((2, 20)));
425 assert_eq!(lru_queue.pop(), None);
426
427 lru_queue.put(1, 10);
429 lru_queue.put(2, 20);
430 lru_queue.put(3, 30);
431 lru_queue.get(&2);
432 lru_queue.get(&3);
433 lru_queue.get(&1);
434 assert_eq!(lru_queue.pop(), Some((2, 20)));
435 assert_eq!(lru_queue.pop(), Some((3, 30)));
436 assert_eq!(lru_queue.pop(), Some((1, 10)));
437 assert_eq!(lru_queue.pop(), None);
438
439 lru_queue.put(1, 10);
441 lru_queue.put(2, 20);
442 lru_queue.put(3, 30);
443 lru_queue.peek(&2);
444 assert_eq!(lru_queue.pop(), Some((1, 10)));
445 assert_eq!(lru_queue.pop(), Some((2, 20)));
446 assert_eq!(lru_queue.pop(), Some((3, 30)));
447 assert_eq!(lru_queue.pop(), None);
448
449 lru_queue.put(1, 10);
451 lru_queue.put(2, 20);
452 lru_queue.put(3, 30);
453 lru_queue.contains_key(&2);
454 assert_eq!(lru_queue.pop(), Some((1, 10)));
455 assert_eq!(lru_queue.pop(), Some((2, 20)));
456 assert_eq!(lru_queue.pop(), Some((3, 30)));
457 assert_eq!(lru_queue.pop(), None);
458
459 lru_queue.put(1, 10);
461 lru_queue.put(2, 20);
462 lru_queue.put(3, 30);
463 lru_queue.put(2, 21);
464 assert_eq!(lru_queue.pop(), Some((1, 10)));
465 assert_eq!(lru_queue.pop(), Some((3, 30)));
466 assert_eq!(lru_queue.pop(), Some((2, 21)));
467 assert_eq!(lru_queue.pop(), None);
468
469 lru_queue.put(1, 10);
471 lru_queue.put(2, 20);
472 lru_queue.put(3, 30);
473 lru_queue.put(2, 21);
474 lru_queue.put(3, 31);
475 lru_queue.put(1, 11);
476 assert_eq!(lru_queue.pop(), Some((2, 21)));
477 assert_eq!(lru_queue.pop(), Some((3, 31)));
478 assert_eq!(lru_queue.pop(), Some((1, 11)));
479 assert_eq!(lru_queue.pop(), None);
480
481 lru_queue.put(1, 10);
483 lru_queue.put(2, 20);
484 lru_queue.put(3, 30);
485 lru_queue.remove(&2);
486 assert_eq!(lru_queue.pop(), Some((1, 10)));
487 assert_eq!(lru_queue.pop(), Some((3, 30)));
488 assert_eq!(lru_queue.pop(), None);
489
490 lru_queue.put(1, 10);
492 lru_queue.put(2, 20);
493 lru_queue.put(3, 30);
494 lru_queue.remove(&1);
495 assert_eq!(lru_queue.pop(), Some((2, 20)));
496 assert_eq!(lru_queue.pop(), Some((3, 30)));
497 assert_eq!(lru_queue.pop(), None);
498
499 lru_queue.put(1, 10);
501 lru_queue.put(2, 20);
502 lru_queue.put(3, 30);
503 lru_queue.remove(&3);
504 assert_eq!(lru_queue.pop(), Some((1, 10)));
505 assert_eq!(lru_queue.pop(), Some((2, 20)));
506 assert_eq!(lru_queue.pop(), None);
507 }
508
509 #[test]
510 fn test_fuzzy() {
512 let mut lru_queue: LruQueue<i32, i32> = LruQueue::new();
513 let mut map: HashMap<i32, i32> = HashMap::new();
514 let max_keys = 1_000;
515 let methods = ["get", "put", "remove", "pop", "contains", "len"];
516 let mut rng = rand::rng();
517
518 for i in 0..1_000_000 {
519 match *methods.choose(&mut rng).unwrap() {
520 "get" => {
521 assert_eq!(lru_queue.get(&(i % max_keys)), map.get(&(i % max_keys)))
522 }
523 "put" => assert_eq!(
524 lru_queue.put(i % max_keys, i),
525 map.insert(i % max_keys, i)
526 ),
527 "remove" => assert_eq!(
528 lru_queue.remove(&(i % max_keys)),
529 map.remove(&(i % max_keys))
530 ),
531 "pop" => {
532 let removed = lru_queue.pop();
533 if let Some((k, v)) = removed {
534 assert_eq!(Some(v), map.remove(&k))
535 }
536 }
537 "contains" => {
538 assert_eq!(
539 lru_queue.contains_key(&(i % max_keys)),
540 map.contains_key(&(i % max_keys))
541 )
542 }
543 "len" => assert_eq!(lru_queue.len(), map.len()),
544 _ => unreachable!(),
545 }
546 }
547 }
548}