A better Rust ATProto crate
1

Configure Feed

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

at main 5.6 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; 9 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 clear(&mut self) { 30 self.window = Deque::new(CacheRegion::Window); 31 self.probation = Deque::new(CacheRegion::MainProbation); 32 self.protected = Deque::new(CacheRegion::MainProtected); 33 self.write_order = Deque::new(CacheRegion::Other); 34 } 35 36 pub(crate) fn push_back_ao<V>( 37 &mut self, 38 region: CacheRegion, 39 kh: KeyHashDate<K>, 40 entry: &mut ValueEntry<K, V>, 41 ) { 42 let node = Box::new(DeqNode::new(kh)); 43 let node = match region { 44 CacheRegion::Window => self.window.push_back(node), 45 CacheRegion::MainProbation => self.probation.push_back(node), 46 CacheRegion::MainProtected => self.protected.push_back(node), 47 CacheRegion::Other => unreachable!(), 48 }; 49 let tagged_node = TagNonNull::compose(node, region as usize); 50 entry.set_access_order_q_node(Some(tagged_node)); 51 } 52 53 pub(crate) fn push_back_wo<V>(&mut self, kh: KeyDate<K>, entry: &mut ValueEntry<K, V>) { 54 let node = Box::new(DeqNode::new(kh)); 55 let node = self.write_order.push_back(node); 56 entry.set_write_order_q_node(Some(node)); 57 } 58 59 pub(crate) fn move_to_back_ao<V>(&mut self, entry: &ValueEntry<K, V>) { 60 if let Some(tagged_node) = entry.access_order_q_node() { 61 let (node, tag) = tagged_node.decompose(); 62 let p = unsafe { node.as_ref() }; 63 match tag.into() { 64 CacheRegion::Window if self.window.contains(p) => { 65 unsafe { self.window.move_to_back(node) }; 66 } 67 CacheRegion::MainProbation if self.probation.contains(p) => { 68 unsafe { self.probation.move_to_back(node) }; 69 } 70 CacheRegion::MainProtected if self.protected.contains(p) => { 71 unsafe { self.protected.move_to_back(node) }; 72 } 73 _ => unreachable!(), 74 } 75 } 76 } 77 78 pub(crate) fn move_to_back_wo<V>(&mut self, entry: &ValueEntry<K, V>) { 79 let node = entry.write_order_q_node().unwrap(); 80 let p = unsafe { node.as_ref() }; 81 if self.write_order.contains(p) { 82 unsafe { self.write_order.move_to_back(node) }; 83 } 84 } 85 86 pub(crate) fn unlink_ao<V>(&mut self, entry: &mut ValueEntry<K, V>) { 87 if let Some(node) = entry.take_access_order_q_node() { 88 self.unlink_node_ao(node); 89 } 90 } 91 92 pub(crate) fn unlink_ao_from_deque<V>( 93 deq_name: &str, 94 deq: &mut Deque<KeyHashDate<K>>, 95 entry: &mut ValueEntry<K, V>, 96 ) { 97 if let Some(node) = entry.take_access_order_q_node() { 98 unsafe { Self::unlink_node_ao_from_deque(deq_name, deq, node) }; 99 } 100 } 101 102 pub(crate) fn unlink_wo<V>(deq: &mut Deque<KeyDate<K>>, entry: &mut ValueEntry<K, V>) { 103 if let Some(node) = entry.take_write_order_q_node() { 104 Self::unlink_node_wo(deq, node); 105 } 106 } 107 108 pub(crate) fn unlink_node_ao(&mut self, tagged_node: TagNonNull<DeqNode<KeyHashDate<K>>, 2>) { 109 unsafe { 110 match tagged_node.decompose_tag().into() { 111 CacheRegion::Window => { 112 Self::unlink_node_ao_from_deque("window", &mut self.window, tagged_node) 113 } 114 CacheRegion::MainProbation => { 115 Self::unlink_node_ao_from_deque("probation", &mut self.probation, tagged_node) 116 } 117 CacheRegion::MainProtected => { 118 Self::unlink_node_ao_from_deque("protected", &mut self.protected, tagged_node) 119 } 120 _ => unreachable!(), 121 } 122 } 123 } 124 125 unsafe fn unlink_node_ao_from_deque( 126 deq_name: &str, 127 deq: &mut Deque<KeyHashDate<K>>, 128 tagged_node: TagNonNull<DeqNode<KeyHashDate<K>>, 2>, 129 ) { 130 let (node, tag) = tagged_node.decompose(); 131 if deq.region() == tag && deq.contains(node.as_ref()) { 132 // https://github.com/moka-rs/moka/issues/64 133 deq.unlink_and_drop(node); 134 } else { 135 panic!( 136 "unlink_node - node is not a member of {} deque. {:?}", 137 deq_name, 138 node.as_ref() 139 ) 140 } 141 } 142 143 pub(crate) fn unlink_node_wo(deq: &mut Deque<KeyDate<K>>, node: NonNull<DeqNode<KeyDate<K>>>) { 144 unsafe { 145 let p = node.as_ref(); 146 if deq.contains(p) { 147 // https://github.com/moka-rs/moka/issues/64 148 deq.unlink_and_drop(node); 149 } else { 150 panic!( 151 "unlink_node - node is not a member of write_order deque. {:?}", 152 p 153 ) 154 } 155 } 156 } 157}