anndata_memory/base/
mod.rs1use std::{
2 fmt,
3 ops::{Deref, DerefMut},
4 sync::Arc,
5};
6
7
8
9pub trait DeepClone {
11 fn deep_clone(&self) -> Self;
12}
13
14use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
15
16pub struct RwSlot<T>(Arc<RwLock<Option<T>>>);
17
18impl<T> Clone for RwSlot<T> {
19 fn clone(&self) -> Self {
20 self.shallow_clone()
21 }
22}
23
24impl<T: DeepClone> DeepClone for RwSlot<T> {
25 fn deep_clone(&self) -> Self {
26 let inner = self.lock_read();
27 match inner.as_ref() {
28 Some(value) => RwSlot::new(value.deep_clone()),
29 None => RwSlot::none(),
30 }
31 }
32}
33
34impl<T> fmt::Display for RwSlot<T>
35where
36 T: fmt::Display,
37{
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 if self.is_none() {
40 write!(f, "Empty or closed slot")
41 } else {
42 write!(f, "{}", self.read_inner().deref())
43 }
44 }
45}
46
47impl<T> RwSlot<T> {
48 pub fn new(x: T) -> Self {
49 RwSlot(Arc::new(RwLock::new(Some(x))))
50 }
51
52 pub fn none() -> Self {
53 RwSlot(Arc::new(RwLock::new(None)))
54 }
55
56 pub fn is_none(&self) -> bool {
57 self.lock_read().is_none()
58 }
59
60 pub fn lock_read(&self) -> RwLockReadGuard<'_, Option<T>> {
61 self.0.read()
62 }
63
64 pub fn lock_read_recursive(&self) -> RwLockReadGuard<'_, Option<T>> {
65 self.0.read_recursive()
66 }
67
68 pub fn lock_write(&self) -> RwLockWriteGuard<'_, Option<T>> {
69 self.0.write()
70 }
71
72 pub fn read_inner(&self) -> ReadInner<'_, T> {
73 ReadInner(self.0.read())
74 }
75
76 pub fn write_inner(&self) -> WriteInner<'_, T> {
77 WriteInner(self.0.write())
78 }
79
80 pub fn insert(&self, data: T) -> Option<T> {
81 std::mem::replace(&mut self.lock_write(), Some(data))
82 }
83
84 pub fn extract(&self) -> Option<T> {
85 self.lock_write().take()
86 }
87
88 pub fn shallow_clone(&self) -> Self {
89 RwSlot(Arc::clone(&self.0))
90 }
91
92 pub fn drop(&self) {
93 let _ = self.extract();
94 }
95
96 pub fn swap(&self, other: &Self) {
97 let mut self_lock = self.lock_write();
98 let mut other_lock = other.lock_write();
99 std::mem::swap(self_lock.deref_mut(), other_lock.deref_mut());
100 }
101}
102
103pub struct ReadInner<'a, T>(pub RwLockReadGuard<'a, Option<T>>);
104
105impl<T> Deref for ReadInner<'_, T> {
106 type Target = T;
107
108 fn deref(&self) -> &Self::Target {
109 self.0.as_ref().expect("accessing an empty slot")
110 }
111}
112
113pub struct WriteInner<'a, T>(pub RwLockWriteGuard<'a, Option<T>>);
114
115impl<T> Deref for WriteInner<'_, T> {
116 type Target = T;
117
118 fn deref(&self) -> &Self::Target {
119 self.0.as_ref().expect("accessing an empty slot")
120 }
121}
122
123impl<T> DerefMut for WriteInner<'_, T> {
124 fn deref_mut(&mut self) -> &mut Self::Target {
125 self.0.as_mut().expect("accessing an empty slot")
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132
133 #[test]
134 fn create_slot_with_value() {
135 let slot = RwSlot::new(10);
136 assert!(!slot.is_none());
137 assert_eq!(*slot.read_inner(), 10);
138 }
139
140 #[test]
141 fn create_empty_slot() {
142 let slot: RwSlot<i32> = RwSlot::none();
143 assert!(slot.is_none());
144 }
145
146 #[test]
147 fn insert_and_extract_value() {
148 let slot = RwSlot::new(10);
149 assert_eq!(slot.extract(), Some(10));
150 assert!(slot.is_none());
151 }
152
153 #[test]
154 fn insert_value_into_empty_slot() {
155 let slot: RwSlot<i32> = RwSlot::none();
156 assert!(slot.is_none());
157 assert_eq!(slot.insert(20), None);
158 assert_eq!(*slot.read_inner(), 20);
159 }
160
161 #[test]
162 fn swap_slots() {
163 let slot1 = RwSlot::new(10);
164 let slot2 = RwSlot::new(20);
165 slot1.swap(&slot2);
166 assert_eq!(*slot1.read_inner(), 20);
167 assert_eq!(*slot2.read_inner(), 10);
168 }
169
170 #[test]
171 fn modify_inner_value() {
172 let slot = RwSlot::new(10);
173 {
174 let mut inner = slot.write_inner();
175 *inner = 30;
176 }
177 assert_eq!(*slot.read_inner(), 30);
178 }
179
180 #[test]
181 fn display_slot() {
182 let slot = RwSlot::new(10);
183 assert_eq!(format!("{}", slot), "10");
184 slot.extract();
185 assert_eq!(format!("{}", slot), "Empty or closed slot");
186 }
187
188 #[test]
189 fn test_shallow_clone() {
190 let original = RwSlot::new(vec![1, 2, 3]);
191 let cloned = original.shallow_clone();
192
193 assert_eq!(*original.read_inner(), *cloned.read_inner());
195
196 original.write_inner().push(4);
198
199 assert_eq!(*original.read_inner(), vec![1, 2, 3, 4]);
201 assert_eq!(*cloned.read_inner(), vec![1, 2, 3, 4]);
202 }
203
204 #[test]
205 fn test_default_clone() {
206 let original = RwSlot::new(vec![1, 2, 3]);
207 let cloned = original.clone();
208
209 assert_eq!(*original.read_inner(), *cloned.read_inner());
211
212 original.write_inner().push(4);
214
215 assert_eq!(*original.read_inner(), vec![1, 2, 3, 4]);
217 assert_eq!(*cloned.read_inner(), vec![1, 2, 3, 4]);
218 }
219}