Skip to main content

consecutive_vecmap/
lib.rs

1#[cfg(test)]
2extern crate rand;
3#[cfg(test)]
4use rand::Rng;
5
6use std::collections::VecDeque;
7use std::collections::vec_deque::Iter as VecDequeIter;
8use std::collections::vec_deque::IterMut as VecDequeIterMut;
9
10#[derive(Debug)]
11enum Entry<V> {
12    Empty,
13    Full(V)
14}
15
16#[derive(Debug)]
17pub struct ConsecVecMap<V> {
18    head: Option<isize>,
19    deque: VecDeque<Entry<V>>,
20    len: usize,
21}
22
23pub struct Iter<'a, V: 'a> {
24    internal: VecDequeIter<'a, Entry<V>>,
25    iteration: isize,
26}
27
28pub struct IterMut<'a, V: 'a> {
29    internal: VecDequeIterMut<'a, Entry<V>>,
30    iteration: isize,
31}
32
33impl <V> Entry<V> {
34    pub fn is_empty(&self) -> bool {
35        match self {
36            &Entry::Empty => true,
37            &Entry::Full(_) => false
38        }
39    }
40
41    pub fn is_full(&self) -> bool {
42        !self.is_empty()
43    }
44
45    pub fn to_option(self) -> Option<V> {
46        match self {
47            Entry::Empty => None,
48            Entry::Full(v) => Some(v)
49        }
50    }
51}
52
53impl <V> ConsecVecMap<V> {
54    /// Constructs a new empty ConsecVecMap
55    pub fn new() -> ConsecVecMap<V> {
56        ConsecVecMap {
57            head: None,
58            deque: VecDeque::new(),
59            len: 0
60        }
61    }
62
63    /// Constructs a new empty ConsecVecMap with a given capacity
64    pub fn with_capacity(capacity: usize) -> ConsecVecMap<V> {
65        ConsecVecMap {
66            head: None,
67            deque: VecDeque::with_capacity(capacity),
68            len: 0
69        }
70    }
71
72    /// Checks to see if the map is empty
73    pub fn is_empty(&self) -> bool {
74        self.deque.is_empty()
75    }
76
77    /// Returns the number of items that are inside the map
78    pub fn len(&self) -> usize {
79        self.len
80    }
81
82    pub fn get(&self, key: isize) -> Option<&V> {
83        if let Some(head) = self.head {
84            if key < head || key >= head + self.deque.len() as isize {
85                None
86            } else {
87                match &self.deque[(key - head) as usize] {
88                    &Entry::Empty => None,
89                    &Entry::Full(ref value) => Some(value)
90                }
91            }
92        } else {
93            None
94        }
95    }
96
97    pub fn get_mut(&mut self, key: isize) -> Option<&mut V> {
98        unsafe { std::mem::transmute(self.get(key)) }
99    }
100
101    /// Inserts a new key-value pair into the map
102    pub fn insert(&mut self, key: isize, value: V) -> Option<V> {
103        use std::mem::swap;
104        if let Some(head) = self.head {
105            if key < head {
106                let diff = head - key;
107                for _ in 0 .. diff - 1 {
108                    self.deque.push_front(Entry::Empty);
109                }
110                self.deque.push_front(Entry::Full(value));
111                self.head = Some(key);
112                self.len += 1;
113                None
114            } else if key < head + self.deque.len() as isize {
115                let mut filled = Entry::Full(value);
116                swap(&mut filled, &mut self.deque[(key - head) as usize]);
117                if filled.is_empty() {
118                    self.len += 1;
119                }
120                filled.to_option()
121            } else {
122                let diff = key - (head + self.deque.len() as isize);
123                for _ in 0 .. diff {
124                    self.deque.push_back(Entry::Empty);
125                }
126                self.deque.push_back(Entry::Full(value));
127                self.len += 1;
128                None
129            }
130        } else {
131            debug_assert!(self.deque.is_empty());
132            debug_assert!(self.len == 0);
133            self.deque.push_back(Entry::Full(value));
134            self.len = 1;
135            self.head = Some(key);
136            None
137        }
138    }
139
140    /// Tries to remove the object with the associated key
141    pub fn remove(&mut self, key: isize) -> Option<V> {
142        use std::mem::swap;
143        if let Some(head) = self.head {
144            if key < head || key >= head + self.deque.len() as isize {
145                None
146            } else {
147                let mut slot = Entry::Empty;
148                swap(&mut slot, &mut self.deque[(key - head) as usize]);
149                self.maintain();
150                if slot.is_full() {
151                    self.len -= 1;
152                }
153                slot.to_option()
154            }
155        } else {
156            None
157        }
158    }
159
160    /// Checks to see if this map contains a key
161    pub fn contains_key(&mut self, key: isize) -> bool {
162        if let Some(head) = self.head {
163            if key < head || key >= head + self.deque.len() as isize {
164                false
165            } else {
166                self.deque[(key - head) as usize].is_full()
167            }
168        } else {
169            false
170        }
171    }
172
173    /// Returns an iterator over (isize, &V)
174    pub fn iter(&self) -> Iter<V> {
175        Iter {
176            internal: self.deque.iter(),
177            iteration: self.head.unwrap_or(0)
178        }
179    }
180
181    /// Returns an iterator over (isize, &mut V)
182    pub fn iter_mut(&mut self) -> IterMut<V> {
183        IterMut {
184            internal: self.deque.iter_mut(),
185            iteration: self.head.unwrap_or(0)
186        }
187    }
188
189    fn maintain(&mut self) {
190        for _ in 0 .. self.deque.len() {
191            if self.deque[0].is_empty() {
192                self.deque.pop_front();
193                if let Some(head) = self.head.as_mut() {
194                    *head += 1;
195                }
196            } else if self.deque[self.deque.len() - 1].is_empty() {
197                self.deque.pop_back();
198            } else {
199                break;
200            }
201        }
202        if self.deque.is_empty() {
203            self.head == None;
204        } else {
205        }
206    }
207}
208
209impl <'a, V> Iterator for Iter<'a, V> {
210    type Item = (isize, &'a V);
211
212    fn next(&mut self) -> Option<(isize, &'a V)> {
213        match self.internal.next() {
214            Some(&Entry::Empty) => {
215                self.iteration += 1;
216                self.next()
217            }
218            Some(&Entry::Full(ref v)) => {
219                let r = (self.iteration, v);
220                self.iteration += 1;
221                Some(r)
222            }
223            None => None
224        }
225    }
226}
227
228impl <'a, V> Iterator for IterMut<'a, V> {
229    type Item = (isize, &'a mut V);
230
231    fn next(&mut self) -> Option<(isize, &'a mut V)> {
232        match self.internal.next() {
233            Some(&mut Entry::Empty) => {
234                self.iteration += 1;
235                self.next()
236            }
237            Some(&mut Entry::Full(ref mut v)) => {
238                let r = (self.iteration, v);
239                self.iteration += 1;
240                Some(r)
241            }
242            None => None
243        }
244    }
245}
246
247#[test]
248fn single_insert() {
249    let mut map = ConsecVecMap::new();
250    map.insert(0, 10);
251    assert!(!map.is_empty());
252    assert!(map.len() == 1);
253    assert!(map.contains_key(0));
254    assert!(map.get(0) == Some(&10));
255    assert!(map.get_mut(0) == Some(&mut 10));
256    assert!(map.remove(0) == Some(10));
257    assert!(map.is_empty());
258    assert!(map.len() == 0);
259}
260
261#[test]
262fn multi_insert() {
263    for x in 0 .. 100 {
264        let mut map = ConsecVecMap::new();
265        let mut count = 0;
266        for i in (x + 1) .. (x + 10) {
267            let mut k = i * i;
268            count += 1;
269
270            assert!(map.insert(i, k).is_none());
271            assert!(!map.is_empty());
272            assert_eq!(map.len(), count);
273            assert!(map.contains_key(i));
274            assert!(map.get(i) == Some(&k));
275            assert!(map.get_mut(i) == Some(&mut k));
276        }
277
278        for i in (x + 1) .. (x + 10) {
279            let k = i * i;
280            count -= 1;
281
282            assert!(map.remove(i) == Some(k));
283            println!("{:#?}", map);
284            assert!(!map.contains_key(i));
285            assert!(map.get(i).is_none());
286            assert_eq!(map.len(), count);
287        }
288
289        assert!(map.is_empty());
290        assert!(map.len() == 0);
291    }
292}
293
294#[test]
295fn regression() {
296    let mut map = ConsecVecMap::new();
297    assert!(map.insert(0, ()).is_none());
298    assert!(map.insert(75, ()).is_none());
299    println!("{:?}", map);
300    println!("{:?}", map.len());
301    println!("{:?}", map.deque.len());
302    assert!(map.insert(74, ()).is_none());
303}
304
305#[test]
306fn fuzz() {
307    for _ in 0 .. 100 {
308        println!("============");
309        let mut random_vec: Vec<_> = (-100 .. 100).collect();
310        let mut map = ConsecVecMap::new();
311        let mut iter = 0;
312        rand::thread_rng().shuffle(&mut random_vec);
313
314        for i in random_vec.iter().cloned() {
315            let i_3 = i * i * i;
316            iter += 1;
317
318            assert_eq!(map.insert(i, i_3), None);
319            assert!(!map.is_empty());
320            assert_eq!(map.len(), iter);
321        }
322
323        assert_eq!(map.deque.len(), iter);
324
325        for i in random_vec.iter().cloned() {
326            let i_3 = i * i * i;
327            iter -= 1;
328
329            assert_eq!(map.remove(i), Some(i_3));
330            assert_eq!(map.len(), iter);
331        }
332        assert_eq!(map.len(), 0);
333        assert!(map.is_empty());
334    }
335}