anndata_memory/base/
mod.rs

1use std::{
2    fmt,
3    ops::{Deref, DerefMut},
4    sync::Arc,
5};
6
7
8
9/// Trait for types that can be cloned shallowly and deeply
10pub 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        // Verify that the cloned value is equal to the original
194        assert_eq!(*original.read_inner(), *cloned.read_inner());
195
196        // Modify the original to ensure the clone shares the same data
197        original.write_inner().push(4);
198
199        // Verify that the modification affects both original and clone
200        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        // Verify that the cloned value is equal to the original
210        assert_eq!(*original.read_inner(), *cloned.read_inner());
211
212        // Modify the original to ensure the clone shares the same data
213        original.write_inner().push(4);
214
215        // Verify that the modification affects both original and clone
216        assert_eq!(*original.read_inner(), vec![1, 2, 3, 4]);
217        assert_eq!(*cloned.read_inner(), vec![1, 2, 3, 4]);
218    }
219}