A better Rust ATProto crate
1use crate::common::{deque::DeqNode, time::Instant};
2
3use std::{ptr::NonNull, sync::Arc};
4use tagptr::TagNonNull;
5use triomphe::Arc as TrioArc;
6
7pub(crate) mod constants;
8pub(crate) mod deques;
9pub(crate) mod entry_info;
10pub(crate) mod housekeeper;
11
12pub(crate) mod atomic_time;
13
14use self::entry_info::EntryInfo;
15
16pub(crate) type Weigher<K, V> = Arc<dyn Fn(&K, &V) -> u32 + Send + Sync + 'static>;
17
18pub(crate) trait AccessTime {
19 fn last_accessed(&self) -> Option<Instant>;
20 fn set_last_accessed(&self, timestamp: Instant);
21 fn last_modified(&self) -> Option<Instant>;
22 fn set_last_modified(&self, timestamp: Instant);
23}
24
25pub(crate) struct KeyHash<K> {
26 pub(crate) key: Arc<K>,
27 pub(crate) hash: u64,
28}
29
30impl<K> KeyHash<K> {
31 pub(crate) fn new(key: Arc<K>, hash: u64) -> Self {
32 Self { key, hash }
33 }
34}
35
36impl<K> Clone for KeyHash<K> {
37 fn clone(&self) -> Self {
38 Self {
39 key: Arc::clone(&self.key),
40 hash: self.hash,
41 }
42 }
43}
44
45pub(crate) struct KeyDate<K> {
46 key: Arc<K>,
47 entry_info: TrioArc<EntryInfo<K>>,
48}
49
50impl<K> KeyDate<K> {
51 pub(crate) fn new(key: Arc<K>, entry_info: &TrioArc<EntryInfo<K>>) -> Self {
52 Self {
53 key,
54 entry_info: TrioArc::clone(entry_info),
55 }
56 }
57
58 pub(crate) fn key(&self) -> &Arc<K> {
59 &self.key
60 }
61}
62
63pub(crate) struct KeyHashDate<K> {
64 key: Arc<K>,
65 hash: u64,
66 entry_info: TrioArc<EntryInfo<K>>,
67}
68
69impl<K> KeyHashDate<K> {
70 pub(crate) fn new(kh: KeyHash<K>, entry_info: &TrioArc<EntryInfo<K>>) -> Self {
71 Self {
72 key: kh.key,
73 hash: kh.hash,
74 entry_info: TrioArc::clone(entry_info),
75 }
76 }
77
78 pub(crate) fn key(&self) -> &Arc<K> {
79 &self.key
80 }
81
82 pub(crate) fn hash(&self) -> u64 {
83 self.hash
84 }
85
86 pub(crate) fn entry_info(&self) -> &EntryInfo<K> {
87 &self.entry_info
88 }
89}
90
91pub(crate) struct KvEntry<K, V> {
92 pub(crate) key: Arc<K>,
93 pub(crate) entry: TrioArc<ValueEntry<K, V>>,
94}
95
96impl<K, V> KvEntry<K, V> {
97 pub(crate) fn new(key: Arc<K>, entry: TrioArc<ValueEntry<K, V>>) -> Self {
98 Self { key, entry }
99 }
100}
101
102impl<K> AccessTime for DeqNode<KeyDate<K>> {
103 #[inline]
104 fn last_accessed(&self) -> Option<Instant> {
105 None
106 }
107
108 #[inline]
109 fn set_last_accessed(&self, _timestamp: Instant) {
110 unreachable!();
111 }
112
113 #[inline]
114 fn last_modified(&self) -> Option<Instant> {
115 self.element.entry_info.last_modified()
116 }
117
118 #[inline]
119 fn set_last_modified(&self, timestamp: Instant) {
120 self.element.entry_info.set_last_modified(timestamp);
121 }
122}
123
124impl<K> AccessTime for DeqNode<KeyHashDate<K>> {
125 #[inline]
126 fn last_accessed(&self) -> Option<Instant> {
127 self.element.entry_info.last_accessed()
128 }
129
130 #[inline]
131 fn set_last_accessed(&self, timestamp: Instant) {
132 self.element.entry_info.set_last_accessed(timestamp);
133 }
134
135 #[inline]
136 fn last_modified(&self) -> Option<Instant> {
137 None
138 }
139
140 #[inline]
141 fn set_last_modified(&self, _timestamp: Instant) {
142 unreachable!();
143 }
144}
145
146// DeqNode for an access order queue.
147pub(crate) type KeyDeqNodeAo<K> = TagNonNull<DeqNode<KeyHashDate<K>>, 2>;
148
149// DeqNode for the write order queue.
150pub(crate) type KeyDeqNodeWo<K> = NonNull<DeqNode<KeyDate<K>>>;
151
152pub(crate) struct ValueEntry<K, V> {
153 pub(crate) value: V,
154 info: TrioArc<EntryInfo<K>>,
155}
156
157impl<K, V> ValueEntry<K, V> {
158 pub(crate) fn new(value: V, entry_info: TrioArc<EntryInfo<K>>) -> Self {
159 Self {
160 value,
161 info: entry_info,
162 }
163 }
164
165 pub(crate) fn entry_info(&self) -> &TrioArc<EntryInfo<K>> {
166 &self.info
167 }
168
169 pub(crate) fn is_admitted(&self) -> bool {
170 self.info.is_admitted()
171 }
172
173 pub(crate) fn set_admitted(&self, value: bool) {
174 self.info.set_admitted(value);
175 }
176
177 pub(crate) fn is_dirty(&self) -> bool {
178 self.info.is_dirty()
179 }
180
181 pub(crate) fn set_dirty(&self, value: bool) {
182 self.info.set_dirty(value);
183 }
184
185 #[inline]
186 pub(crate) fn policy_weight(&self) -> u32 {
187 self.info.policy_weight()
188 }
189
190 pub(crate) fn access_order_q_node(&self) -> Option<KeyDeqNodeAo<K>> {
191 self.info.access_order_q_node()
192 }
193
194 pub(crate) fn set_access_order_q_node(&self, node: Option<KeyDeqNodeAo<K>>) {
195 self.info.set_access_order_q_node(node);
196 }
197
198 pub(crate) fn take_access_order_q_node(&self) -> Option<KeyDeqNodeAo<K>> {
199 self.info.take_access_order_q_node()
200 }
201
202 pub(crate) fn write_order_q_node(&self) -> Option<KeyDeqNodeWo<K>> {
203 self.info.write_order_q_node()
204 }
205
206 pub(crate) fn set_write_order_q_node(&self, node: Option<KeyDeqNodeWo<K>>) {
207 self.info.set_write_order_q_node(node)
208 }
209
210 pub(crate) fn take_write_order_q_node(&self) -> Option<KeyDeqNodeWo<K>> {
211 self.info.take_write_order_q_node()
212 }
213
214 pub(crate) fn unset_q_nodes(&self) {
215 self.info.unset_q_nodes();
216 }
217}
218
219impl<K, V> AccessTime for TrioArc<ValueEntry<K, V>> {
220 #[inline]
221 fn last_accessed(&self) -> Option<Instant> {
222 self.info.last_accessed()
223 }
224
225 #[inline]
226 fn set_last_accessed(&self, timestamp: Instant) {
227 self.info.set_last_accessed(timestamp);
228 }
229
230 #[inline]
231 fn last_modified(&self) -> Option<Instant> {
232 self.info.last_modified()
233 }
234
235 #[inline]
236 fn set_last_modified(&self, timestamp: Instant) {
237 self.info.set_last_modified(timestamp);
238 }
239}
240
241pub(crate) enum ReadOp<K, V> {
242 // u64 is the hash of the key.
243 Hit(u64, TrioArc<ValueEntry<K, V>>, Instant),
244 Miss(u64),
245}
246
247pub(crate) enum WriteOp<K, V> {
248 Upsert {
249 key_hash: KeyHash<K>,
250 value_entry: TrioArc<ValueEntry<K, V>>,
251 old_weight: u32,
252 new_weight: u32,
253 },
254 Remove(KvEntry<K, V>),
255}