1mod builder;
7mod cache;
8mod deques;
9mod iter;
10
11use std::{ptr::NonNull, rc::Rc};
12use tagptr::TagNonNull;
13
14pub use builder::CacheBuilder;
15pub use cache::Cache;
16pub use iter::Iter;
17
18use crate::common::{deque::DeqNode, time::Instant};
19
20pub(crate) type Weigher<K, V> = Box<dyn FnMut(&K, &V) -> u32>;
21
22pub(crate) trait AccessTime {
23 fn last_accessed(&self) -> Option<Instant>;
24 fn set_last_accessed(&mut self, timestamp: Instant);
25 fn last_modified(&self) -> Option<Instant>;
26 fn set_last_modified(&mut self, timestamp: Instant);
27}
28
29pub(crate) struct KeyDate<K> {
30 pub(crate) key: Rc<K>,
31 pub(crate) timestamp: Option<Instant>,
32}
33
34impl<K> KeyDate<K> {
35 pub(crate) fn new(key: Rc<K>, timestamp: Option<Instant>) -> Self {
36 Self { key, timestamp }
37 }
38}
39
40pub(crate) struct KeyHashDate<K> {
41 pub(crate) key: Rc<K>,
42 pub(crate) hash: u64,
43 pub(crate) timestamp: Option<Instant>,
44}
45
46impl<K> KeyHashDate<K> {
47 pub(crate) fn new(key: Rc<K>, hash: u64, timestamp: Option<Instant>) -> Self {
48 Self {
49 key,
50 hash,
51 timestamp,
52 }
53 }
54}
55
56type KeyDeqNodeAo<K> = TagNonNull<DeqNode<KeyHashDate<K>>, 2>;
58
59type KeyDeqNodeWo<K> = NonNull<DeqNode<KeyDate<K>>>;
61
62struct EntryInfo<K> {
63 access_order_q_node: Option<KeyDeqNodeAo<K>>,
64 write_order_q_node: Option<KeyDeqNodeWo<K>>,
65 policy_weight: u32,
66}
67
68pub(crate) struct ValueEntry<K, V> {
69 pub(crate) value: V,
70 info: EntryInfo<K>,
71}
72
73impl<K, V> ValueEntry<K, V> {
74 pub(crate) fn new(value: V, policy_weight: u32) -> Self {
75 Self {
76 value,
77 info: EntryInfo {
78 access_order_q_node: None,
79 write_order_q_node: None,
80 policy_weight,
81 },
82 }
83 }
84
85 #[inline]
86 pub(crate) fn replace_deq_nodes_with(&mut self, mut other: Self) {
87 self.info.access_order_q_node = other.info.access_order_q_node.take();
88 self.info.write_order_q_node = other.info.write_order_q_node.take();
89 }
90
91 #[inline]
92 pub(crate) fn access_order_q_node(&self) -> Option<KeyDeqNodeAo<K>> {
93 self.info.access_order_q_node
94 }
95
96 #[inline]
97 pub(crate) fn set_access_order_q_node(&mut self, node: Option<KeyDeqNodeAo<K>>) {
98 self.info.access_order_q_node = node;
99 }
100
101 #[inline]
102 pub(crate) fn take_access_order_q_node(&mut self) -> Option<KeyDeqNodeAo<K>> {
103 self.info.access_order_q_node.take()
104 }
105
106 #[inline]
107 pub(crate) fn write_order_q_node(&self) -> Option<KeyDeqNodeWo<K>> {
108 self.info.write_order_q_node
109 }
110
111 #[inline]
112 pub(crate) fn set_write_order_q_node(&mut self, node: Option<KeyDeqNodeWo<K>>) {
113 self.info.write_order_q_node = node;
114 }
115
116 #[inline]
117 pub(crate) fn take_write_order_q_node(&mut self) -> Option<KeyDeqNodeWo<K>> {
118 self.info.write_order_q_node.take()
119 }
120
121 #[inline]
122 pub(crate) fn policy_weight(&self) -> u32 {
123 self.info.policy_weight
124 }
125
126 #[inline]
127 pub(crate) fn set_policy_weight(&mut self, policy_weight: u32) {
128 self.info.policy_weight = policy_weight;
129 }
130}
131
132impl<K, V> AccessTime for ValueEntry<K, V> {
133 #[inline]
134 fn last_accessed(&self) -> Option<Instant> {
135 self.access_order_q_node()
136 .and_then(|node| unsafe { node.as_ref() }.element.timestamp)
137 }
138
139 #[inline]
140 fn set_last_accessed(&mut self, timestamp: Instant) {
141 if let Some(mut node) = self.info.access_order_q_node {
142 unsafe { node.as_mut() }.set_last_accessed(timestamp);
143 }
144 }
145
146 #[inline]
147 fn last_modified(&self) -> Option<Instant> {
148 self.write_order_q_node()
149 .and_then(|node| unsafe { node.as_ref() }.element.timestamp)
150 }
151
152 #[inline]
153 fn set_last_modified(&mut self, timestamp: Instant) {
154 if let Some(mut node) = self.info.write_order_q_node {
155 unsafe { node.as_mut() }.set_last_modified(timestamp);
156 }
157 }
158}
159
160impl<K> AccessTime for DeqNode<KeyDate<K>> {
161 #[inline]
162 fn last_accessed(&self) -> Option<Instant> {
163 None
164 }
165
166 #[inline]
167 fn set_last_accessed(&mut self, _timestamp: Instant) {
168 unreachable!();
169 }
170
171 #[inline]
172 fn last_modified(&self) -> Option<Instant> {
173 self.element.timestamp
174 }
175
176 #[inline]
177 fn set_last_modified(&mut self, timestamp: Instant) {
178 self.element.timestamp = Some(timestamp);
179 }
180}
181
182impl<K> AccessTime for DeqNode<KeyHashDate<K>> {
183 #[inline]
184 fn last_accessed(&self) -> Option<Instant> {
185 self.element.timestamp
186 }
187
188 #[inline]
189 fn set_last_accessed(&mut self, timestamp: Instant) {
190 self.element.timestamp = Some(timestamp);
191 }
192
193 #[inline]
194 fn last_modified(&self) -> Option<Instant> {
195 None
196 }
197
198 #[inline]
199 fn set_last_modified(&mut self, _timestamp: Instant) {
200 unreachable!();
201 }
202}