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}