limited_table/
lib.rs

1extern crate slab;
2
3use slab::Slab;
4
5pub type Key = usize;
6
7pub struct LimitedTable<Item> {
8    slab: Slab<Item>,
9    begin: Key,
10    limit: usize,
11}
12
13impl<Item> LimitedTable<Item> {
14    pub fn new(begin: Key, limit: usize) -> Self {
15        Self {
16            slab: Slab::with_capacity(limit),
17            begin,
18            limit,
19        }
20    }
21
22    pub fn limit(&self) -> usize {
23        self.limit
24    }
25
26    pub fn len(&self) -> usize {
27        self.slab.len()
28    }
29
30    pub fn is_empty(&self) -> bool {
31        self.len() == 0
32    }
33
34    pub fn capacity(&self) -> usize {
35        let capacity = self.slab.capacity();
36        debug_assert_eq!(self.limit(), capacity);
37        capacity
38    }
39
40    pub fn is_full(&self) -> bool {
41        self.limit() == self.len()
42    }
43
44    pub fn insert(&mut self, item: Item) -> Option<Key> {
45        if self.is_full() {
46            return None;
47        }
48        Some(self.begin + self.slab.insert(item))
49    }
50
51    pub fn remove(&mut self, key: Key) -> Option<Item> {
52        if key < self.begin {
53            return None;
54        }
55        let key = key - self.begin;
56        if !self.slab.contains(key) {
57            return None;
58        }
59        Some(self.slab.remove(key))
60    }
61
62    pub fn contains(&self, key: Key) -> bool {
63        self.slab.contains(key - self.begin)
64    }
65
66    pub fn get(&self, key: Key) -> Option<&Item> {
67        self.slab.get(key - self.begin)
68    }
69
70    pub fn clear(&mut self) {
71        self.slab.clear()
72    }
73}
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78
79    struct TestItem;
80
81    #[test]
82    fn limit() {
83        let begin = 11;
84        let limit = 54;
85        let table: LimitedTable<TestItem> = LimitedTable::new(begin, limit);
86        assert_eq!(limit, table.limit());
87    }
88
89    #[test]
90    fn empty_table_len_is_zero() {
91        let begin = 11;
92        let limit = 54;
93        let table: LimitedTable<TestItem> = LimitedTable::new(begin, limit);
94        assert_eq!(0, table.len());
95    }
96
97    #[test]
98    fn len_of_inserted_table() {
99        let begin: Key = 11;
100        let limit: usize = 54;
101        let mut table: LimitedTable<TestItem> = LimitedTable::new(begin, limit);
102        assert_eq!(0, table.len());
103        let t1 = table.insert(TestItem);
104        assert!(t1.is_some());
105        assert_eq!(1, table.len());
106        let t2 = table.insert(TestItem);
107        assert!(t2.is_some());
108        assert_eq!(2, table.len());
109        let t3 = table.insert(TestItem);
110        assert!(t3.is_some());
111        assert_eq!(3, table.len());
112        let t4 = table.insert(TestItem);
113        assert!(t4.is_some());
114        assert_eq!(4, table.len());
115    }
116
117    #[test]
118    fn get_returns_none_when_the_item_is_removed() {
119        let begin: Key = 11;
120        let limit: usize = 54;
121        let mut table: LimitedTable<TestItem> = LimitedTable::new(begin, limit);
122        let t1 = table.insert(TestItem);
123        assert!(t1.is_some());
124        let t2 = table.insert(TestItem);
125        assert!(t2.is_some());
126        let t3 = table.insert(TestItem);
127        assert!(t3.is_some());
128        let t4 = table.insert(TestItem);
129        assert!(t4.is_some());
130        assert!(table.get(t4.unwrap()).is_some());
131        let _ = table.remove(t4.unwrap());
132        assert!(table.get(t4.unwrap()).is_none());
133    }
134
135    #[test]
136    fn insert_returns_none_when_the_table_is_full() {
137        let begin: Key = 11;
138        let limit: usize = 20;
139        let mut table: LimitedTable<TestItem> = LimitedTable::new(begin, limit);
140        for _ in begin..(begin + limit) {
141            let t = table.insert(TestItem);
142            assert!(table.get(t.unwrap()).is_some());
143        }
144        let t = table.insert(TestItem);
145        assert!(t.is_none());
146    }
147
148    #[test]
149    fn contains_returns_true_when_item_is_inserted() {
150        let begin: Key = 11;
151        let limit: usize = 54;
152        let mut table: LimitedTable<TestItem> = LimitedTable::new(begin, limit);
153        let t1 = table.insert(TestItem);
154        assert_ne!(None, t1);
155        assert!(table.contains(t1.unwrap()));
156    }
157}