A better Rust ATProto crate
1

Configure Feed

Select the types of activity you want to include in your feed.

at main 5.9 kB View raw
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}