A better Rust ATProto crate
0
fork

Configure Feed

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

at main 202 lines 5.2 kB view raw
1//! Provides a *not* thread-safe cache implementation built upon 2//! [`std::collections::HashMap`][std-hashmap]. 3//! 4//! [std-hashmap]: https://doc.rust-lang.org/std/collections/struct.HashMap.html 5 6mod 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 56// DeqNode for an access order queue. 57type KeyDeqNodeAo<K> = TagNonNull<DeqNode<KeyHashDate<K>>, 2>; 58 59// DeqNode for the write order queue. 60type 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}