A better Rust ATProto crate
1

Configure Feed

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

at main 6.3 kB View raw
1use super::{KeyDate, KeyHashDate, ValueEntry}; 2use crate::common::{ 3 deque::{DeqNode, Deque}, 4 CacheRegion, 5}; 6 7use std::ptr::NonNull; 8use tagptr::TagNonNull; 9use triomphe::Arc as TrioArc; 10pub(crate) struct Deques<K> { 11 pub(crate) window: Deque<KeyHashDate<K>>, // Not used yet. 12 pub(crate) probation: Deque<KeyHashDate<K>>, 13 pub(crate) protected: Deque<KeyHashDate<K>>, // Not used yet. 14 pub(crate) write_order: Deque<KeyDate<K>>, 15} 16 17impl<K> Default for Deques<K> { 18 fn default() -> Self { 19 Self { 20 window: Deque::new(CacheRegion::Window), 21 probation: Deque::new(CacheRegion::MainProbation), 22 protected: Deque::new(CacheRegion::MainProtected), 23 write_order: Deque::new(CacheRegion::Other), 24 } 25 } 26} 27 28impl<K> Deques<K> { 29 pub(crate) fn push_back_ao<V>( 30 &mut self, 31 region: CacheRegion, 32 khd: KeyHashDate<K>, 33 entry: &TrioArc<ValueEntry<K, V>>, 34 ) { 35 let node = Box::new(DeqNode::new(khd)); 36 let node = match region { 37 CacheRegion::Window => self.window.push_back(node), 38 CacheRegion::MainProbation => self.probation.push_back(node), 39 CacheRegion::MainProtected => self.protected.push_back(node), 40 _ => unreachable!(), 41 }; 42 let tagged_node = TagNonNull::compose(node, region as usize); 43 entry.set_access_order_q_node(Some(tagged_node)); 44 } 45 46 pub(crate) fn push_back_wo<V>(&mut self, kd: KeyDate<K>, entry: &TrioArc<ValueEntry<K, V>>) { 47 let node = Box::new(DeqNode::new(kd)); 48 let node = self.write_order.push_back(node); 49 entry.set_write_order_q_node(Some(node)); 50 } 51 52 pub(crate) fn move_to_back_ao<V>(&mut self, entry: &TrioArc<ValueEntry<K, V>>) { 53 if let Some(tagged_node) = entry.access_order_q_node() { 54 let (node, tag) = tagged_node.decompose(); 55 let p = unsafe { node.as_ref() }; 56 match tag.into() { 57 CacheRegion::Window if self.window.contains(p) => { 58 unsafe { self.window.move_to_back(node) }; 59 } 60 CacheRegion::MainProbation if self.probation.contains(p) => { 61 unsafe { self.probation.move_to_back(node) }; 62 } 63 CacheRegion::MainProtected if self.protected.contains(p) => { 64 unsafe { self.protected.move_to_back(node) }; 65 } 66 _ => unreachable!(), 67 } 68 } 69 } 70 71 pub(crate) fn move_to_back_ao_in_deque<V>( 72 deq_name: &str, 73 deq: &mut Deque<KeyHashDate<K>>, 74 entry: &TrioArc<ValueEntry<K, V>>, 75 ) { 76 if let Some(tagged_node) = entry.access_order_q_node() { 77 let (node, tag) = tagged_node.decompose(); 78 let p = unsafe { node.as_ref() }; 79 if deq.region() == tag { 80 if deq.contains(p) { 81 unsafe { deq.move_to_back(node) }; 82 } 83 } else { 84 panic!( 85 "move_to_back_ao_in_deque - node is not a member of {} deque. {:?}", 86 deq_name, p, 87 ) 88 } 89 } 90 } 91 92 pub(crate) fn move_to_back_wo<V>(&mut self, entry: &TrioArc<ValueEntry<K, V>>) { 93 if let Some(node) = entry.write_order_q_node() { 94 let p = unsafe { node.as_ref() }; 95 if self.write_order.contains(p) { 96 unsafe { self.write_order.move_to_back(node) }; 97 } 98 } 99 } 100 101 pub(crate) fn move_to_back_wo_in_deque<V>( 102 deq: &mut Deque<KeyDate<K>>, 103 entry: &TrioArc<ValueEntry<K, V>>, 104 ) { 105 if let Some(node) = entry.write_order_q_node() { 106 let p = unsafe { node.as_ref() }; 107 if deq.contains(p) { 108 unsafe { deq.move_to_back(node) }; 109 } 110 } 111 } 112 113 pub(crate) fn unlink_ao<V>(&mut self, entry: &TrioArc<ValueEntry<K, V>>) { 114 if let Some(node) = entry.take_access_order_q_node() { 115 self.unlink_node_ao(node); 116 } 117 } 118 119 pub(crate) fn unlink_ao_from_deque<V>( 120 deq_name: &str, 121 deq: &mut Deque<KeyHashDate<K>>, 122 entry: &TrioArc<ValueEntry<K, V>>, 123 ) { 124 if let Some(node) = entry.take_access_order_q_node() { 125 unsafe { Self::unlink_node_ao_from_deque(deq_name, deq, node) }; 126 } 127 } 128 129 pub(crate) fn unlink_wo<V>(deq: &mut Deque<KeyDate<K>>, entry: &TrioArc<ValueEntry<K, V>>) { 130 if let Some(node) = entry.take_write_order_q_node() { 131 Self::unlink_node_wo(deq, node); 132 } 133 } 134 135 pub(crate) fn unlink_node_ao(&mut self, tagged_node: TagNonNull<DeqNode<KeyHashDate<K>>, 2>) { 136 unsafe { 137 match tagged_node.decompose_tag().into() { 138 CacheRegion::Window => { 139 Self::unlink_node_ao_from_deque("window", &mut self.window, tagged_node) 140 } 141 CacheRegion::MainProbation => { 142 Self::unlink_node_ao_from_deque("probation", &mut self.probation, tagged_node) 143 } 144 CacheRegion::MainProtected => { 145 Self::unlink_node_ao_from_deque("protected", &mut self.protected, tagged_node) 146 } 147 _ => unreachable!(), 148 } 149 } 150 } 151 152 unsafe fn unlink_node_ao_from_deque( 153 deq_name: &str, 154 deq: &mut Deque<KeyHashDate<K>>, 155 tagged_node: TagNonNull<DeqNode<KeyHashDate<K>>, 2>, 156 ) { 157 let (node, tag) = tagged_node.decompose(); 158 let p = node.as_ref(); 159 if deq.region() == tag { 160 if deq.contains(p) { 161 // https://github.com/moka-rs/moka/issues/64 162 deq.unlink_and_drop(node); 163 } 164 } else { 165 panic!( 166 "unlink_node - node is not a member of {} deque. {:?}", 167 deq_name, p 168 ) 169 } 170 } 171 172 pub(crate) fn unlink_node_wo(deq: &mut Deque<KeyDate<K>>, node: NonNull<DeqNode<KeyDate<K>>>) { 173 unsafe { 174 let p = node.as_ref(); 175 if deq.contains(p) { 176 // https://github.com/moka-rs/moka/issues/64 177 deq.unlink_and_drop(node); 178 } 179 } 180 } 181}