1#[derive(Clone, Debug)]
3
4pub struct LRUList<T> {
5 values: Vec<ListEntry<T>>,
6}
7
8#[derive(Clone, Debug)]
9struct ListEntry<T> {
10 value: Option<T>,
11 next: usize,
12 prev: usize,
13}
14
15impl<T> LRUList<T> {
19 const FREE: usize = 0;
20 const OCCUPIED: usize = 1;
21
22 pub(crate) fn with_capacity(capacity: usize) -> LRUList<T> {
23 let mut values = Vec::with_capacity(capacity + 2);
24 values.push(ListEntry::<T> {
25 value: None,
26 next: 0,
27 prev: 0,
28 });
29 values.push(ListEntry::<T> {
30 value: None,
31 next: 1,
32 prev: 1,
33 });
34 LRUList { values }
35 }
36
37 pub(crate) fn unlink(&mut self, index: usize) {
38 let prev = self.values[index].prev;
39 let next = self.values[index].next;
40 self.values[prev].next = next;
41 self.values[next].prev = prev;
42 }
43
44 pub(crate) fn link_after(&mut self, index: usize, prev: usize) {
45 let next = self.values[prev].next;
46 self.values[index].prev = prev;
47 self.values[index].next = next;
48 self.values[prev].next = index;
49 self.values[next].prev = index;
50 }
51
52 pub(crate) fn move_to_front(&mut self, index: usize) {
53 self.unlink(index);
54 self.link_after(index, Self::OCCUPIED);
55 }
56
57 pub(crate) fn push_front(&mut self, value: T) -> usize {
58 if self.values[Self::FREE].next == Self::FREE {
59 self.values.push(ListEntry::<T> {
60 value: None,
61 next: Self::FREE,
62 prev: Self::FREE,
63 });
64 self.values[Self::FREE].next = self.values.len() - 1;
65 }
66 let index = self.values[Self::FREE].next;
67 self.values[index].value = Some(value);
68 self.unlink(index);
69 self.link_after(index, Self::OCCUPIED);
70 index
71 }
72
73 pub(crate) fn remove(&mut self, index: usize) -> T {
74 self.unlink(index);
75 self.link_after(index, Self::FREE);
76 self.values[index].value.take().expect("invalid index")
77 }
78
79 pub(crate) fn back(&self) -> usize {
80 self.values[Self::OCCUPIED].prev
81 }
82
83 pub(crate) fn get(&self, index: usize) -> &T {
84 self.values[index].value.as_ref().expect("invalid index")
85 }
86
87 pub(crate) fn get_mut(&mut self, index: usize) -> &mut T {
88 self.values[index].value.as_mut().expect("invalid index")
89 }
90
91 pub(crate) fn set(&mut self, index: usize, value: T) -> Option<T> {
92 self.values[index].value.replace(value)
93 }
94
95 pub(crate) fn clear(&mut self) {
96 self.values.clear();
97 self.values.push(ListEntry::<T> {
98 value: None,
99 next: 0,
100 prev: 0,
101 });
102 self.values.push(ListEntry::<T> {
103 value: None,
104 next: 1,
105 prev: 1,
106 });
107 }
108
109 pub fn iter(&self) -> LRUListIterator<T> {
110 LRUListIterator::<T> {
111 list: self,
112 index: Self::OCCUPIED,
113 }
114 }
115}
116
117#[derive(Debug)]
118pub struct LRUListIterator<'a, T> {
119 list: &'a LRUList<T>,
120 index: usize,
121}
122
123impl<'a, T> Iterator for LRUListIterator<'a, T> {
124 type Item = &'a T;
125
126 fn next(&mut self) -> Option<Self::Item> {
127 let next = self.list.values[self.index].next;
128 if next == LRUList::<T>::OCCUPIED {
129 None
130 } else {
131 let value = self.list.values[next].value.as_ref();
132 self.index = next;
133 value
134 }
135 }
136}