minimum/slab/
rc_slab.rs

1use super::GenSlab;
2use super::GenSlabKey;
3use super::SlabIndexT;
4use std::sync::Arc;
5use std::sync::Weak;
6
7//TODO: Since we have Arc indirection, is a generation index really necessary?
8pub struct RcSlabEntry<T> {
9    slab_key: Arc<GenSlabKey<T>>,
10}
11
12impl<T> RcSlabEntry<T> {
13    pub fn new(slab_key: GenSlabKey<T>) -> Self {
14        RcSlabEntry {
15            slab_key: Arc::new(slab_key),
16        }
17    }
18
19    pub fn downgrade(&self) -> WeakSlabEntry<T> {
20        WeakSlabEntry::new(self)
21    }
22}
23
24impl<T> Clone for RcSlabEntry<T> {
25    fn clone(&self) -> Self {
26        RcSlabEntry::<T> {
27            slab_key: Arc::clone(&self.slab_key),
28        }
29    }
30}
31
32impl<T> PartialEq for RcSlabEntry<T> {
33    fn eq(&self, other: &Self) -> bool {
34        self.slab_key == other.slab_key
35    }
36}
37
38impl<T> Eq for RcSlabEntry<T> {}
39
40impl<T> std::hash::Hash for RcSlabEntry<T> {
41    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
42        self.slab_key.hash(state);
43    }
44}
45
46impl<T> std::fmt::Debug for RcSlabEntry<T> {
47    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
48        (*self.slab_key).fmt(f)
49    }
50}
51
52pub struct WeakSlabEntry<T> {
53    slab_key: Weak<GenSlabKey<T>>,
54}
55
56impl<T> WeakSlabEntry<T> {
57    pub fn new(slab_entry: &RcSlabEntry<T>) -> Self {
58        WeakSlabEntry {
59            slab_key: Arc::downgrade(&slab_entry.slab_key),
60        }
61    }
62
63    pub fn upgrade(&self) -> Option<RcSlabEntry<T>> {
64        Some(RcSlabEntry {
65            slab_key: self.slab_key.upgrade()?,
66        })
67    }
68
69    pub fn can_upgrade(&self) -> bool {
70        //self.slab_key.weak_count()
71        unimplemented!()
72    }
73}
74
75//impl<T> std::clone::Clone for WeakSlabEntry<T> {
76//    fn clone(&self) -> Self {
77//        WeakSlabEntry::<T> {
78//            slab_key = Weak::<T>::clone(&self.slab_key)
79//        }
80//    }
81//}
82
83pub struct RcSlab<T> {
84    slab: GenSlab<T>,
85    entries: Vec<RcSlabEntry<T>>,
86}
87
88impl<T> RcSlab<T> {
89    pub fn new() -> Self {
90        let initial_count: SlabIndexT = 32;
91        let entries = Vec::with_capacity(initial_count as usize);
92
93        RcSlab::<T> {
94            slab: GenSlab::<T>::new(),
95            entries: entries,
96        }
97    }
98
99    pub fn allocate(&mut self, value: T) -> RcSlabEntry<T> {
100        let key = self.slab.allocate(value);
101        let entry = RcSlabEntry::new(key);
102        self.entries.push(entry.clone());
103        entry
104    }
105
106    pub fn get(&self, slab_entry: &RcSlabEntry<T>) -> &T {
107        self.slab.get(&*slab_entry.slab_key).unwrap()
108    }
109
110    pub fn get_mut(&mut self, slab_entry: &RcSlabEntry<T>) -> &mut T {
111        self.slab.get_mut(&*slab_entry.slab_key).unwrap()
112    }
113
114    pub fn iter(&self) -> impl Iterator<Item = &T> {
115        self.slab.iter()
116    }
117
118    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
119        self.slab.iter_mut()
120    }
121
122    pub fn active_count(&self) -> usize {
123        self.slab.active_count()
124    }
125
126    pub fn update(&mut self) {
127        for index in (0..self.entries.len()).rev() {
128            if Arc::strong_count(&self.entries[index].slab_key) == 1 {
129                self.slab.free(&self.entries[index].slab_key);
130                self.entries.swap_remove(index);
131            }
132        }
133    }
134}
135
136#[cfg(test)]
137mod tests {
138    use super::*;
139
140    struct TestStruct {
141        value: u32,
142    }
143
144    impl TestStruct {
145        fn new(value: u32) -> Self {
146            TestStruct { value }
147        }
148    }
149
150    #[test]
151    fn test_rc_allocate_deallocate_one() {
152        let mut pool = RcSlab::<TestStruct>::new();
153        let value = TestStruct::new(123);
154        {
155            let _entry = pool.allocate(value);
156            assert_eq!(1, pool.active_count());
157        }
158
159        assert_eq!(1, pool.active_count());
160        pool.update();
161        assert_eq!(0, pool.active_count());
162    }
163
164    #[test]
165    fn test_rc_get_success() {
166        let mut pool = RcSlab::<TestStruct>::new();
167        let mut keys = vec![];
168
169        for i in 0..10 {
170            let value = TestStruct::new(i);
171            let key = pool.allocate(value);
172            keys.push(key);
173        }
174
175        assert_eq!(10, pool.active_count());
176        assert_eq!(5, pool.get(&keys[5]).value);
177    }
178
179    #[test]
180    fn test_rc_get_mut_success() {
181        let mut pool = RcSlab::<TestStruct>::new();
182        let mut keys = vec![];
183
184        for i in 0..10 {
185            let value = TestStruct::new(i);
186            let key = pool.allocate(value);
187            keys.push(key);
188        }
189
190        assert_eq!(10, pool.active_count());
191        assert_eq!(5, pool.get_mut(&keys[5]).value);
192    }
193}