1#[forbid(unsafe_code)]
46
47pub mod arena {
48 use std::fmt::Display;
68
69 #[derive(Debug, PartialEq, Clone, Copy)]
72 pub struct Index {
73 pub idx: usize,
74 pub generation: u64,
75 }
76
77 #[derive(Debug, PartialEq)]
81 pub enum Entry<T> {
82 Free { next_free: Option<usize> },
83 Occupied { value: T, generation: u64 },
84 }
85
86 pub struct Arena<T> {
93 items: Vec<Entry<T>>,
94 capacity: usize,
95
96 generation: u64,
97
98 free_list_head: Option<usize>,
99 }
100
101 #[derive(Debug, Clone, PartialEq)]
103 pub struct ArenaOOM;
104
105 impl Display for ArenaOOM {
106 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107 write!(f, "Arena out of memory.")
108 }
109 }
110
111 impl<T> Default for Arena<T> {
112 fn default() -> Self {
113 Self::new()
114 }
115 }
116
117 impl<T> Arena<T> {
118 pub fn new() -> Self {
119 Arena {
120 items: Vec::new(),
121 capacity: 0,
122 generation: 0,
123 free_list_head: None,
124 }
125 }
126
127 pub fn capacity(&self) -> usize {
128 self.capacity
129 }
130
131 pub fn reserve(&mut self, capacity: usize) {
132 self.items.reserve_exact(capacity);
133 let start = self.items.len();
134 let end = start + capacity;
135 let old_free = self.free_list_head;
136 self.items.extend((start..end).map(|i| {
137 if i == end - 1 {
138 Entry::Free {
139 next_free: old_free,
140 }
141 } else {
142 Entry::Free {
143 next_free: Some(i + 1),
144 }
145 }
146 }));
147 self.free_list_head = Some(start);
148 self.capacity += capacity;
149 }
150
151 pub fn with_capacity(capacity: usize) -> Self {
152 let mut arena = Self::new();
153 arena.reserve(capacity);
154 arena
155 }
156
157 pub fn insert(&mut self, item: T) -> Result<Index, ArenaOOM> {
158 if self.free_list_head.is_none() {
159 return Err(ArenaOOM {});
160 }
161
162 let old_free = self.free_list_head;
163 if let Entry::Free { next_free } = self.items[old_free.unwrap()] {
164 self.free_list_head = next_free;
165 } else {
166 return Err(ArenaOOM {});
167 }
168
169 let entry = Entry::Occupied {
170 value: item,
171 generation: self.generation,
172 };
173 self.items[old_free.unwrap()] = entry;
174 self.generation += 1;
175
176 Ok(Index {
177 idx: old_free.unwrap(),
178 generation: self.generation - 1,
179 })
180 }
181
182 pub fn remove(&mut self, index: &Index) -> Option<T> {
183 if let Some(Entry::Occupied {
184 value: _,
185 generation,
186 }) = self.items.get(index.idx)
187 {
188 if &index.generation != generation {
189 return None;
190 }
191
192 let entry = Entry::<T>::Free {
193 next_free: self.free_list_head,
194 };
195
196 let old_entry = core::mem::replace(&mut self.items[index.idx], entry);
197
198 self.free_list_head = Some(index.idx);
199
200 if let Entry::Occupied {
201 value,
202 generation: _,
203 } = old_entry
204 {
205 return Some(value);
206 }
207 }
208
209 None
210 }
211
212 pub fn get_mut(&mut self, index: &Index) -> Option<&mut T> {
213 if let Some(Entry::Occupied { value, generation }) = self.items.get_mut(index.idx) {
214 if &index.generation == generation {
215 return Some(value);
216 }
217 }
218
219 None
220 }
221
222 pub fn get(&self, index: &Index) -> Option<&T> {
223 if let Some(Entry::Occupied { value, generation }) = self.items.get(index.idx) {
224 if &index.generation == generation {
225 return Some(value);
226 }
227 }
228
229 None
230 }
231 }
232
233 #[cfg(test)]
234 mod tests {
235 use super::*;
236
237 #[test]
238 fn arena_new() {
239 Arena::<i32>::new();
240 }
241
242 #[test]
243 fn arena_with_capacity() {
244 let capacity = 100;
245 let arena = Arena::<i32>::with_capacity(capacity);
246 assert_eq!(arena.capacity(), capacity);
247
248 assert_eq!(arena.free_list_head, Some(0));
249 let mut i = 0;
250 for entry in &arena.items {
251 if i == capacity - 1 {
252 assert_eq!(entry, &Entry::Free { next_free: None })
253 } else {
254 assert_eq!(
255 entry,
256 &Entry::Free {
257 next_free: Some(i + 1)
258 }
259 )
260 }
261
262 i += 1;
263 }
264 }
265
266 #[test]
267 fn arena_insert() {
268 let mut arena = Arena::<i32>::new();
269 assert_eq!(arena.insert(0), Err(ArenaOOM {}));
270
271 arena.reserve(1);
272 let index_0 = arena.insert(0);
273 assert_eq!(
274 index_0,
275 Ok(Index {
276 idx: 0,
277 generation: 0
278 })
279 );
280
281 arena.reserve(1);
282 let index_1 = arena.insert(1);
283 assert_eq!(
284 index_1,
285 Ok(Index {
286 idx: 1,
287 generation: 1
288 })
289 );
290
291 let index_0_val = index_0.unwrap();
292 let item_0 = arena.get(&index_0_val);
293 assert_eq!(item_0, Some(&0));
294
295 let index_1_val = index_1.unwrap();
296 let item_1 = arena.get(&index_1_val);
297 assert_eq!(item_1, Some(&1));
298
299 let item_0 = arena.get_mut(&index_0_val);
300 assert_eq!(item_0, Some(&mut 0));
301 let item_0 = item_0.unwrap();
302 *item_0 = 25;
303
304 let item_0 = arena.get(&index_0_val);
305 assert_eq!(item_0, Some(&25));
306
307 let item_1 = arena.get_mut(&index_1_val);
308 assert_eq!(item_1, Some(&mut 1));
309 let item_1 = item_1.unwrap();
310 *item_1 = -78;
311
312 let item_1 = arena.get(&index_1_val);
313 assert_eq!(item_1, Some(&-78));
314
315 assert_eq!(arena.capacity(), 2);
316 assert_eq!(arena.insert(0), Err(ArenaOOM {}));
317
318 let old_cap = arena.capacity();
319 let to_reserve = 100;
320 arena.reserve(to_reserve);
321 for ele in 0..to_reserve {
322 assert_eq!(
323 arena.insert(0),
324 Ok(Index {
325 idx: old_cap + ele,
326 generation: (old_cap + ele) as u64
327 })
328 )
329 }
330 assert_eq!(arena.capacity(), old_cap + to_reserve);
331 assert_eq!(arena.insert(0), Err(ArenaOOM {}));
332 }
333
334 #[test]
335 fn arena_remove() {
336 let mut arena = Arena::<i32>::with_capacity(1);
337
338 let index = arena.insert(0).unwrap();
339 assert_eq!(arena.get(&index), Some(&0));
340
341 assert_eq!(arena.remove(&index).unwrap(), 0);
342
343 assert_eq!(arena.get(&index), None);
344
345 let index = arena.insert(56).unwrap();
346 assert_eq!(
347 index,
348 Index {
349 idx: 0,
350 generation: 1
351 }
352 );
353
354 assert_eq!(arena.remove(&index).unwrap(), 56);
355 assert!(arena.remove(&index).is_none());
356
357 let current_gen = 2;
358
359 let to_reserve = 5;
360 arena.reserve(to_reserve);
361 for ele in 0..to_reserve + 1 {
362 if ele == to_reserve {
364 assert_eq!(
365 arena.insert(0),
366 Ok(Index {
367 idx: 0,
368 generation: (current_gen + ele) as u64
369 })
370 )
371 } else {
372 assert_eq!(
373 arena.insert(0),
374 Ok(Index {
375 idx: ele + 1,
376 generation: (current_gen + ele) as u64
377 })
378 )
379 }
380 }
381 }
382 }
383}
384
385pub mod list {
386 use std::fmt::Display;
424
425 use crate::arena::{Arena, ArenaOOM, Index};
426
427 #[derive(Debug, Clone, Copy, PartialEq)]
430 pub struct Link {
431 pub index: Index,
432 }
433
434 pub struct Node<T> {
436 pub value: T,
437 pub next: Option<Link>,
438 pub prev: Option<Link>,
439 }
440
441 pub struct LinkedList<T> {
443 arena: Arena<Node<T>>,
444
445 head: Option<Link>,
446 tail: Option<Link>,
447
448 len: usize,
449 }
450
451 pub struct Iter<'a, T: 'a> {
453 list: &'a LinkedList<T>,
454 current: Option<Link>,
455 }
456
457 #[derive(Debug, Clone, PartialEq)]
458 pub enum ListError {
459 LinkBroken,
460 ListOOM(ArenaOOM),
461 ListEmpty,
462 }
463
464 impl Display for ListError {
465 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
466 match &self {
467 ListError::LinkBroken => write!(f, "Link does not point to a valid location."),
468 ListError::ListOOM(arena_oom) => {
469 write!(f, "List out of memory: ")?;
470 arena_oom.fmt(f)
471 }
472 ListError::ListEmpty => write!(f, "List is empty."),
473 }
474 }
475 }
476
477 impl<T> Default for LinkedList<T> {
478 fn default() -> Self {
479 Self::new()
480 }
481 }
482
483 impl<T> LinkedList<T> {
484 pub fn new() -> Self {
485 LinkedList {
486 arena: Arena::new(),
487 head: None,
488 tail: None,
489 len: 0,
490 }
491 }
492
493 pub fn with_capacity(capacity: usize) -> Self {
494 LinkedList {
495 arena: Arena::with_capacity(capacity),
496 head: None,
497 tail: None,
498 len: 0,
499 }
500 }
501
502 pub fn len(&self) -> usize {
503 self.len
504 }
505
506 pub fn is_empty(&self) -> bool {
507 self.head.is_none()
508 }
509
510 pub fn is_full(&self) -> bool {
511 self.len == self.arena.capacity()
512 }
513
514 pub fn reserve(&mut self, capacity: usize) {
515 self.arena.reserve(capacity)
516 }
517
518 pub fn get_mut(&mut self, link: &Link) -> Result<&mut Node<T>, ListError> {
519 let node = self
520 .arena
521 .get_mut(&link.index)
522 .ok_or(ListError::LinkBroken)?;
523 Ok(node)
524 }
525
526 pub fn get_mut_value(&mut self, link: &Link) -> Result<&mut T, ListError> {
527 let node = self.get_mut(link)?;
528 Ok(&mut node.value)
529 }
530
531 pub fn get(&self, link: &Link) -> Result<&Node<T>, ListError> {
532 let node = self.arena.get(&link.index).ok_or(ListError::LinkBroken)?;
533 Ok(node)
534 }
535
536 pub fn push_front(&mut self, value: T) -> Result<Link, ListError> {
537 let node = Node {
538 value,
539 next: self.head,
540 prev: None,
541 };
542
543 let index = self.arena.insert(node).map_err(ListError::ListOOM)?;
544 let link = Link { index };
545 if let Some(head) = self.head {
546 let head_node = self.get_mut(&head)?;
547 head_node.prev = Some(link);
548 } else {
549 self.tail = Some(link);
550 }
551
552 self.head = Some(link);
553
554 self.len += 1;
555 Ok(link)
556 }
557
558 pub fn push_back(&mut self, value: T) -> Result<Link, ListError> {
559 let node = Node {
560 value,
561 next: None,
562 prev: self.tail,
563 };
564
565 let index = self.arena.insert(node).map_err(ListError::ListOOM)?;
566 let link = Link { index };
567 if let Some(tail) = self.tail {
568 let tail_node = self.get_mut(&tail)?;
569 tail_node.next = Some(link);
570 } else {
571 self.head = Some(link)
572 }
573
574 self.tail = Some(link);
575
576 self.len += 1;
577 Ok(link)
578 }
579
580 pub fn head(&self) -> Option<Link> {
581 self.head
582 }
583
584 pub fn tail(&self) -> Option<Link> {
585 self.tail
586 }
587
588 pub fn peek_front(&self) -> Result<&T, ListError> {
589 let head_link = self.head.ok_or(ListError::ListEmpty)?;
590 return self.get(&head_link).map(|x| &x.value);
591 }
592
593 pub fn peek_back(&self) -> Result<&T, ListError> {
594 let tail_link = self.tail.ok_or(ListError::ListEmpty)?;
595 return self.get(&tail_link).map(|x| &x.value);
596 }
597
598 pub fn pop_front(&mut self) -> Result<T, ListError> {
599 let head_link = self.head.ok_or(ListError::ListEmpty)?;
600 let node = self
601 .arena
602 .remove(&head_link.index)
603 .ok_or(ListError::LinkBroken)?;
604
605 self.head = node.next;
606
607 if let Some(link) = self.head {
608 let cur_head_node = self.get_mut(&link)?;
609 cur_head_node.prev = None;
610 } else {
611 self.tail = None;
612 }
613
614 self.len -= 1;
615 Ok(node.value)
616 }
617
618 pub fn pop_back(&mut self) -> Result<T, ListError> {
619 let tail_link = self.tail.ok_or(ListError::ListEmpty)?;
620 let node = self
621 .arena
622 .remove(&tail_link.index)
623 .ok_or(ListError::LinkBroken)?;
624
625 self.tail = node.prev;
626 if let Some(link) = self.tail {
627 let cur_tail_node = self.get_mut(&link)?;
628 cur_tail_node.next = None;
629 } else {
630 self.head = None;
631 }
632
633 self.len -= 1;
634 Ok(node.value)
635 }
636
637 pub fn remove(&mut self, link: &Link) -> Result<T, ListError> {
638 let head = self.head.ok_or(ListError::ListEmpty)?;
639 let tail = self.tail.ok_or(ListError::ListEmpty)?;
640
641 if link == &head {
642 return self.pop_front();
643 }
644
645 if link == &tail {
646 return self.pop_back();
647 }
648
649 let node = self
650 .arena
651 .remove(&link.index)
652 .ok_or(ListError::LinkBroken)?;
653 let prev_link = node.prev.ok_or(ListError::LinkBroken)?;
654 let next_link = node.next.ok_or(ListError::LinkBroken)?;
655
656 let prev = self.get_mut(&prev_link)?;
657 prev.next = Some(next_link);
658
659 let next = self.get_mut(&next_link)?;
660 next.prev = Some(prev_link);
661
662 self.len -= 1;
663 Ok(node.value)
664 }
665
666 pub fn reposition_to_tail(&mut self, link: &Link) -> Result<(), ListError> {
669 let head = self.head.ok_or(ListError::ListEmpty)?;
670 let tail = self.tail.ok_or(ListError::ListEmpty)?;
671
672 if link == &tail {
673 return Ok(());
674 }
675
676 let head_node = self.get_mut(&head)?;
679 if link == &head {
680 self.head = head_node.next;
681 }
682
683 let node = self.get_mut(link)?;
684
685 let prev_link = node.prev;
686 let next_link = node.next;
687
688 node.prev = Some(tail);
689 node.next = None;
690
691 if let Some(link) = prev_link {
692 let prev = self.get_mut(&link)?;
693 prev.next = next_link;
694 }
695
696 if let Some(link) = next_link {
697 let next = self.get_mut(&link)?;
698 next.prev = prev_link;
699 }
700
701 let tail_node = self.get_mut(&tail)?;
702 tail_node.next = Some(*link);
703 self.tail = Some(*link);
704
705 Ok(())
706 }
707
708 pub fn iter(&self) -> Iter<T> {
709 Iter {
710 list: self,
711 current: self.head(),
712 }
713 }
714 }
715
716 impl<'a, T: 'a> Iterator for Iter<'a, T> {
717 type Item = &'a T;
718
719 fn next(&mut self) -> Option<Self::Item> {
720 if let Some(link) = self.current {
721 if let Ok(node) = self.list.get(&link) {
722 self.current = node.next;
723 return Some(&node.value);
724 }
725 }
726
727 None
728 }
729 }
730
731 #[cfg(test)]
732 mod tests {
733 use super::*;
734
735 #[test]
736 fn list_new() {
737 let mut list = LinkedList::<i32>::new();
738 assert!(list.is_empty());
739 assert!(list.is_full());
740
741 assert_eq!(list.peek_front(), Err(ListError::ListEmpty));
742 assert_eq!(list.peek_back(), Err(ListError::ListEmpty));
743
744 assert_eq!(list.push_back(0), Err(ListError::ListOOM(ArenaOOM {})));
745 }
746
747 #[test]
748 fn list_with_capacity() {
749 let capacity = 5;
750 let mut list = LinkedList::<i32>::with_capacity(capacity);
751 assert!(list.is_empty());
752 for _ in 0..capacity {
753 assert!(list.push_back(0).is_ok())
754 }
755 assert!(list.is_full());
756 assert_eq!(list.push_back(0), Err(ListError::ListOOM(ArenaOOM {})));
757 }
758
759 #[test]
760 fn list_push_back() {
761 let capacity = 10;
762 let mut list = LinkedList::<i32>::with_capacity(capacity);
763 for ele in 0..capacity {
764 assert!(list.push_back(ele as i32).is_ok());
765 }
766
767 let mut i = 0;
768 for ele in list.iter() {
769 assert_eq!(ele, &i);
770 i += 1;
771 }
772 }
773
774 #[test]
775 fn list_push_front() {
776 let capacity = 10;
777 let mut list = LinkedList::<i32>::with_capacity(capacity);
778 for ele in 0..capacity {
779 assert!(list.push_front(ele as i32).is_ok());
780 }
781
782 let mut i = capacity as i32 - 1;
783 for ele in list.iter() {
784 assert_eq!(ele, &i);
785 i -= 1;
786 }
787 }
788
789 #[test]
790 fn list_pop_front() {
791 let capacity = 10;
792 let mut list = LinkedList::<i32>::with_capacity(capacity);
793
794 assert_eq!(list.pop_front(), Err(ListError::ListEmpty));
795
796 for ele in 0..capacity {
797 assert!(list.push_back(ele as i32).is_ok());
798 }
799
800 for ele in 0..capacity {
801 assert_eq!(list.pop_front().unwrap(), ele as i32);
802 }
803
804 assert!(list.is_empty());
805 assert_eq!(list.pop_front(), Err(ListError::ListEmpty));
806 }
807
808 #[test]
809 fn list_pop_back() {
810 let capacity = 10;
811 let mut list = LinkedList::<i32>::with_capacity(capacity);
812
813 assert_eq!(list.pop_back(), Err(ListError::ListEmpty));
814
815 for ele in 0..capacity {
816 assert!(list.push_front(ele as i32).is_ok());
817 }
818
819 for ele in 0..capacity {
820 assert_eq!(list.pop_back().unwrap(), ele as i32);
821 }
822
823 assert!(list.is_empty());
824 assert_eq!(list.pop_back(), Err(ListError::ListEmpty));
825 }
826
827 #[test]
828 fn list_remove() {
829 let mut list = LinkedList::<i32>::with_capacity(5);
830 assert!(list.is_empty());
831
832 let link_0 = list.push_back(0).unwrap();
833 let _link_1 = list.push_back(1).unwrap();
834 let link_2 = list.push_back(2).unwrap();
835 let _link_3 = list.push_back(3).unwrap();
836 let link_4 = list.push_back(4).unwrap();
837
838 assert!(list.is_full());
839
840 assert_eq!(list.peek_front().unwrap(), &0);
841 assert_eq!(list.peek_back().unwrap(), &4);
842
843 assert!(list.remove(&link_0).is_ok());
844 assert_eq!(list.len(), 4);
845
846 assert_eq!(list.peek_front().unwrap(), &1);
847 assert_eq!(list.peek_back().unwrap(), &4);
848
849 assert!(list.remove(&link_4).is_ok());
850 assert_eq!(list.len(), 3);
851
852 assert_eq!(list.peek_front().unwrap(), &1);
853 assert_eq!(list.peek_back().unwrap(), &3);
854
855 assert!(list.remove(&link_2).is_ok());
856 assert_eq!(list.len(), 2);
857
858 assert!(list.iter().eq([1, 3].iter()));
859 }
860
861 #[test]
862 fn list_reposition_to_tail() {
863 let capacity = 5;
864
865 let mut list = LinkedList::<i32>::with_capacity(capacity);
866 assert!(list.is_empty());
867
868 for ele in 0..capacity {
869 list.push_back(ele as i32).unwrap();
870 }
871
872 for _ in 0..(capacity / 2) {
873 list.reposition_to_tail(&list.head().unwrap()).unwrap();
874 }
875
876 let mut i = 0;
877 let mut lh = 0 as i32;
878 let mut rh = capacity as i32 / 2;
879 for ele in list.iter() {
880 if i <= (capacity / 2) {
881 assert_eq!(ele, &rh);
882 rh += 1;
883 } else {
884 assert_eq!(ele, &lh);
885 lh += 1;
886 }
887 i += 1
888 }
889
890 let mut list = LinkedList::<i32>::with_capacity(2);
891 let link_0 = list.push_back(0).unwrap();
892 list.reposition_to_tail(&link_0).unwrap();
893 assert_eq!(Some(link_0), list.head());
894 assert_eq!(Some(link_0), list.tail());
895
896 let link_1 = list.push_back(1).unwrap();
897
898 list.reposition_to_tail(&link_0).unwrap();
899 assert_eq!(list.get_mut_value(&link_0), Ok(&mut 0));
900
901 assert_eq!(list.head(), Some(link_1));
902 assert_eq!(list.tail(), Some(link_0));
903
904 list.reserve(1);
905 list.push_back(2).unwrap();
906 list.reposition_to_tail(&link_0).unwrap();
907
908 assert!(list.iter().eq([1, 2, 0].iter()));
909 }
910 }
911}
912
913pub mod lrucache {
914 use crate::list::{Link, LinkedList, ListError};
959 use std::{collections::HashMap, fmt::Display, hash::Hash};
960
961 pub struct Block<K, V> {
963 pub key: K,
964 pub value: V,
965 }
966
967 pub struct LRUCache<K, V>
970 where
971 K: Eq + Hash,
972 {
973 blocks: LinkedList<Block<K, V>>,
974 block_refs: HashMap<K, Link>,
975 }
976
977 #[derive(Debug, Clone, PartialEq)]
978 pub enum CacheError {
979 CacheBroken(ListError),
980 CacheMiss,
981 }
982
983 impl Display for CacheError {
984 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
985 match &self {
986 CacheError::CacheBroken(list_error) => {
987 write!(f, "Cache storage is broken: ")?;
988 list_error.fmt(f)
989 }
990 CacheError::CacheMiss => write!(f, "Key not found in cache."),
991 }
992 }
993 }
994
995 impl<K, V> LRUCache<K, V>
996 where
997 K: Eq + Hash + Copy,
998 {
999 pub fn with_capacity(capacity: usize) -> Self {
1002 LRUCache {
1003 blocks: LinkedList::with_capacity(capacity),
1004 block_refs: HashMap::new(),
1005 }
1006 }
1007
1008 pub fn query(&mut self, key: &K) -> Result<&V, CacheError> {
1012 let link = self.block_refs.get(key).ok_or(CacheError::CacheMiss)?;
1013 self.blocks
1014 .reposition_to_tail(link)
1015 .map_err(CacheError::CacheBroken)?;
1016 let node = self.blocks.get(link).map_err(CacheError::CacheBroken)?;
1017 Ok(&node.value.value)
1018 }
1019
1020 pub fn remove(&mut self, key: &K) -> Result<V, CacheError> {
1025 let link = self.block_refs.remove(key).ok_or(CacheError::CacheMiss)?;
1026 let block = self.blocks.remove(&link).map_err(CacheError::CacheBroken)?;
1027 Ok(block.value)
1028 }
1029
1030 pub fn insert(&mut self, key: K, value: V) -> Result<(), CacheError> {
1033 if let Some(link) = self.block_refs.get(&key) {
1034 self.blocks
1035 .reposition_to_tail(link)
1036 .map_err(CacheError::CacheBroken)?;
1037 let block_ref = self
1038 .blocks
1039 .get_mut_value(link)
1040 .map_err(CacheError::CacheBroken)?;
1041 block_ref.value = value;
1042 return Ok(());
1043 }
1044
1045 if self.blocks.is_full() {
1046 let block = self.blocks.pop_front().map_err(CacheError::CacheBroken)?;
1047 self.block_refs.remove(&block.key);
1048 }
1049
1050 let link = self
1051 .blocks
1052 .push_back(Block { key, value })
1053 .map_err(CacheError::CacheBroken)?;
1054 self.block_refs.insert(key, link);
1055
1056 Ok(())
1057 }
1058 }
1059
1060 #[cfg(test)]
1061 mod tests {
1062 use super::*;
1063
1064 #[test]
1065 fn lru_cache_consistency() {
1066 let mut lru_cache = LRUCache::<i32, i32>::with_capacity(0);
1067 assert_eq!(
1068 lru_cache.insert(0, 0),
1069 Err(CacheError::CacheBroken(ListError::ListEmpty))
1070 );
1071
1072 let mut lru_cache = LRUCache::<i32, i32>::with_capacity(2);
1073 assert!(lru_cache.insert(1, 1).is_ok());
1074 assert!(lru_cache.insert(2, 2).is_ok());
1075 assert_eq!(lru_cache.query(&1), Ok(&1));
1076 assert!(lru_cache.insert(3, 3).is_ok());
1077 assert_eq!(lru_cache.query(&2), Err(CacheError::CacheMiss));
1078 assert!(lru_cache.insert(1, -1).is_ok());
1079 assert_eq!(lru_cache.query(&1), Ok(&-1));
1080 assert!(lru_cache.insert(4, 4).is_ok());
1081 assert_eq!(lru_cache.query(&3), Err(CacheError::CacheMiss));
1082
1083 let capacity = 5;
1084
1085 let mut lru_cache = LRUCache::<i32, i32>::with_capacity(capacity);
1086 assert_eq!(lru_cache.query(&0), Err(CacheError::CacheMiss));
1087
1088 for ele in 0..capacity {
1089 let x = ele as i32;
1090 assert!(lru_cache.insert(x, x).is_ok());
1091 }
1092
1093 for ele in 0..capacity {
1094 let x = ele as i32;
1095 assert_eq!(lru_cache.query(&x), Ok(&x));
1096 }
1097
1098 let x = capacity as i32;
1099 assert!(lru_cache.insert(x, x).is_ok());
1100
1101 assert_eq!(lru_cache.query(&x), Ok(&x));
1102
1103 assert_eq!(lru_cache.query(&0), Err(CacheError::CacheMiss));
1104
1105 let x = capacity as i32 / 2;
1106 assert_eq!(lru_cache.remove(&x), Ok(x));
1107
1108 assert_eq!(lru_cache.query(&x), Err(CacheError::CacheMiss));
1109 assert_eq!(lru_cache.remove(&x), Err(CacheError::CacheMiss));
1110 }
1111 }
1112}