id_map/
lib.rs

1//! [`IdMap`] is a container that gives each item a unique id. Adding and removing by index is O(1).
2//! 
3//! # Examples
4//! 
5//! ```
6//! # use id_map::IdMap;
7//! #
8//! let mut map = IdMap::new();
9//! let blue_id = map.insert("blue");
10//! let red_id = map.insert("red");
11//!
12//! map.retain(|_, &color| color != "red");
13//!
14//! assert!(!map.contains(red_id));
15//! assert_eq!(map[blue_id], "blue");
16//! ```
17//! 
18//! [`IdMap`]: struct.IdMap.html
19
20#![deny(missing_docs, missing_debug_implementations)]
21
22extern crate id_set;
23
24#[cfg(test)]
25mod tests;
26
27pub use id_set::Id;
28
29use std::iter::FromIterator;
30use std::ops::{Index, IndexMut};
31use std::{cmp, fmt, mem, ptr};
32
33use id_set::IdSet;
34
35/// A container that gives each item a unique id. Internally all elements are stored contiguously.
36pub struct IdMap<T> {
37    // The set of valid indices for values.
38    ids: IdSet,
39    // The buffer of values. Indices not in ids are invalid.
40    values: Vec<T>,
41    // The smallest empty space in the vector of values, or values.capacity() if no space is left.
42    space: Id,
43}
44
45impl<T> IdMap<T> {
46    #[inline]
47    /// Creates an empty `IdMap<T>`.
48    pub fn new() -> Self {
49        IdMap {
50            ids: IdSet::new(),
51            values: Vec::new(),
52            space: 0,
53        }
54    }
55
56    #[inline]
57    /// Creates an `IdMap<T>` with the specified capacity.
58    pub fn with_capacity(cap: usize) -> Self {
59        IdMap {
60            ids: IdSet::with_capacity(cap),
61            values: Vec::with_capacity(cap),
62            space: 0,
63        }
64    }
65
66    #[inline]
67    /// Removes all values from the map.
68    pub fn clear(&mut self) {
69        unsafe { self.drop_values() }
70        self.ids.clear();
71    }
72
73    #[inline]
74    /// Returns the id that a subsequent call to insert() will produce.
75    pub fn next_id(&self) -> Id {
76        self.space
77    }
78
79    #[inline]
80    /// Returns the number of id-value pairs in the map.
81    pub fn len(&self) -> usize {
82        self.ids.len()
83    }
84
85    #[inline]
86    /// Returns the number of id-value pairs the map can hold before reallocating.
87    pub fn capacity(&self) -> usize {
88        self.ids.capacity()
89    }
90
91    #[inline]
92    /// Resizes the map such that that `capacity() >= cap`.
93    pub fn reserve(&mut self, cap: usize) {
94        self.ids.reserve(cap);
95        self.values.reserve(cap);
96    }
97
98    #[inline]
99    /// Resizes the map to minimize allocated memory.
100    pub fn shrink_to_fit(&mut self) {
101        self.ids.shrink_to_fit();
102        unsafe {
103            let cap = cmp::min(self.values.capacity(), self.ids.capacity());
104            self.values.set_len(cap);
105            self.values.shrink_to_fit();
106            self.values.set_len(0);
107        }
108    }
109
110    #[inline]
111    /// Returns a reference to the set of valid ids.
112    pub fn as_set(&self) -> &IdSet {
113        &self.ids
114    }
115
116    #[inline]
117    /// Inserts a value into an empty slot in the map and returns its id.
118    pub fn insert(&mut self, val: T) -> Id {
119        let id = self.space;
120        if id == self.values.capacity() {
121            self.values.reserve(id + 1);
122        }
123        unsafe { ptr::write(self.values.get_unchecked_mut(id), val) }
124        self.ids.insert(id);
125        self.find_space();
126        id
127    }
128
129    #[inline]
130    /// Inserts a value at a specific id, returning the old value if it existed.
131    pub fn insert_at(&mut self, id: Id, val: T) -> Option<T> {
132        if self.ids.insert(id) {
133            // val was not previously in the map.
134            if id == self.space {
135                self.find_space();
136            }
137            if self.values.capacity() < id + 1 {
138                self.values.reserve(id + 1);
139            }
140            unsafe { ptr::write(self.values.get_unchecked_mut(id), val) }
141            None
142        } else {
143            // val was previously in the map
144            Some(mem::replace(unsafe { self.values.get_unchecked_mut(id) }, val))
145        }
146    }
147
148    #[inline]
149    /// Removes an id from the map, returning its value if it was previously in the map.
150    pub fn remove(&mut self, id: Id) -> Option<T> {
151        if self.ids.remove(id) {
152            self.space = cmp::min(self.space, id);
153            Some(unsafe { ptr::read(self.values.get_unchecked(id)) })
154        } else {
155            None
156        }
157    }
158
159    #[inline]
160    /// If the id has a value, returns it, otherwise inserts a new value.
161    pub fn get_or_insert(&mut self, id: Id, val: T) -> &mut T {
162        self.get_or_insert_with(id, || val)
163    }
164    
165    #[inline]
166    /// If the id has a value, returns it, otherwise inserts a new value with the provided closure.
167    pub fn get_or_insert_with<F: FnOnce() -> T>(&mut self, id: Id, f: F) -> &mut T {
168        if self.ids.insert(id) {
169            // val was not previously in the map.
170            if id == self.space {
171                self.find_space();
172            }
173            if self.values.capacity() < id + 1 {
174                self.values.reserve(id + 1);
175            }
176            unsafe {
177                let space = self.values.get_unchecked_mut(id);
178                ptr::write(space, f());
179                space
180            }
181        } else {
182            unsafe { self.values.get_unchecked_mut(id) }
183        }
184    }
185
186    #[inline]
187    /// Removes all ids in the set from the map.
188    pub fn remove_set(&mut self, set: &IdSet) {
189        {
190            let mut iter = self.ids.intersection(set).into_iter();
191
192            if let Some(first) = iter.next() {
193                // Set iterators are increasing so we only need to change start once.
194                self.space = cmp::min(self.space, first);
195                unsafe {
196                    ptr::drop_in_place(self.values.get_unchecked_mut(first))
197                }
198                for id in iter {
199                    unsafe {
200                        ptr::drop_in_place(self.values.get_unchecked_mut(id))
201                    }
202                }
203            }
204        }
205
206        self.ids.inplace_difference(set);
207    }
208
209    #[inline]
210    /// Remove all values not satisfying the predicate.
211    pub fn retain<F: FnMut(Id, &T) -> bool>(&mut self, mut pred: F) {
212        let ids = &mut self.ids;
213        let values = &mut self.values;
214        let space = &mut self.space;
215        ids.retain(|id| {
216            unsafe {
217                if pred(id, values.get_unchecked(id)) {
218                    true
219                } else {
220                    *space = cmp::min(*space, id);
221                    ptr::drop_in_place(values.get_unchecked_mut(id));
222                    false
223                }
224            }
225        })
226    }
227
228    #[inline]
229    /// Returns true if the map contains a value for the specified id.
230    pub fn contains(&self, id: Id) -> bool {
231        self.ids.contains(id)
232    }
233
234    #[inline]
235    /// Returns a reference to the value at the specified id if it is in the map.
236    pub fn get(&self, id: Id) -> Option<&T> {
237        if self.ids.contains(id) {
238            Some(unsafe { self.values.get_unchecked(id) })
239        } else {
240            None
241        }
242    }
243
244    #[inline]
245    /// Returns a mutable reference to the value at the specified id if it is in the map.
246    pub fn get_mut(&mut self, id: Id) -> Option<&mut T> {
247        if self.ids.contains(id) {
248            Some(unsafe { self.values.get_unchecked_mut(id) })
249        } else {
250            None
251        }
252    }
253
254    #[inline]
255    /// An iterator over ids, in increasing order.
256    pub fn ids(&self) -> Ids {
257        Ids {
258            ids: self.ids.iter(),
259        }
260    }
261
262    #[inline]
263    /// An iterator over values, in order of increasing id.
264    pub fn values(&self) -> Values<T> {
265        Values {
266            ids: self.ids.iter(),
267            values: self.values.as_ptr(),
268        }
269    }
270
271    #[inline]
272    /// A mutable iterator over values, in order of increasing id.
273    pub fn values_mut(&mut self) -> ValuesMut<T> {
274        ValuesMut {
275            ids: self.ids.iter(),
276            values: self.values.as_mut_ptr(),
277        }
278    }
279
280    #[inline]
281    /// An iterator over id-value pairs, in order of increasing id.
282    pub fn iter(&self) -> Iter<T> {
283        Iter {
284            ids: self.ids.iter(),
285            values: self.values.as_ptr(),
286        }
287    }
288
289    #[inline]
290    /// A mutable iterator over id-value pairs, in order of increasing id.
291    pub fn iter_mut(&mut self) -> IterMut<T> {
292        IterMut {
293            ids: self.ids.iter(),
294            values: self.values.as_mut_ptr(),
295        }
296    }
297
298    #[inline]
299    /// A consuming iterator over id-value pairs, in order of increasing id.
300    pub fn into_iter(self) -> IntoIter<T> {
301        // we cannot move out of self because of the drop impl.
302        let (ids, values) = unsafe {
303            (ptr::read(&self.ids), ptr::read(&self.values))
304        };
305        mem::forget(self);
306        IntoIter {
307            ids: ids.into_iter(),
308            values: values,
309        }
310    }
311
312    #[cfg(test)]
313    fn assert_invariant(&self) {
314        // space should be the minimal empty space.
315        for id in 0..self.space {
316            assert!(self.ids.contains(id));
317        }
318        assert!(!self.ids.contains(self.space));
319        // values.capacity() should an upper bound on ids.
320        for id in &self.ids {
321            assert!(id < self.values.capacity())
322        }
323    }
324
325    /// Clear the values vec. Unsafe since ids is not updated.
326    unsafe fn drop_values(&mut self) {
327        for id in &self.ids {
328            ptr::drop_in_place(self.values.get_unchecked_mut(id))
329        }
330    }
331
332    /// Find the next empty space after has been filled.
333    fn find_space(&mut self) {
334        // Each id corresponds to an entry in the storage so ids can never fill up.
335        self.space += 1;
336        while self.ids.contains(self.space) {
337            self.space += 1;
338        }
339    }
340}
341
342impl<T> Drop for IdMap<T> {
343    #[inline]
344    fn drop(&mut self) {
345        unsafe { self.drop_values() }
346    }
347}
348
349impl<T: Clone> Clone for IdMap<T> {
350    #[inline]
351    fn clone(&self) -> Self {
352        let ids = self.ids.clone();
353        let cap = self.values.capacity();
354        let mut values = Vec::with_capacity(cap);
355        unsafe {
356            for id in &ids {
357                ptr::write(values.get_unchecked_mut(id),
358                           self.values.get_unchecked(id).clone());
359            }
360        }
361        IdMap {
362            ids,
363            values,
364            space: cap,
365        }
366    }
367
368    #[inline]
369    fn clone_from(&mut self, other: &Self) {
370        unsafe { self.drop_values() };
371        self.ids.clone_from(&other.ids);
372
373        let cap = other.values.capacity();
374        self.values.reserve(cap);
375        unsafe {
376            for id in &self.ids {
377                ptr::write(self.values.get_unchecked_mut(id),
378                           other.values.get_unchecked(id).clone());
379            }
380        }
381    }
382}
383
384impl<T: fmt::Debug> fmt::Debug for IdMap<T> {
385    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
386        write!(f, "{{")?;
387        let mut iter = self.iter();
388        if let Some((id, val)) = iter.next() {
389            write!(f, "{:?}: {:?}", id, val)?;
390            for (id, val) in iter {
391                write!(f, ", {:?}: {:?}", id, val)?;
392            }
393        }
394        write!(f, "}}")
395    }
396}
397
398impl<T> Default for IdMap<T> {
399    #[inline]
400    fn default() -> Self {
401        IdMap::new()
402    }
403}
404
405impl<T: Eq> Eq for IdMap<T> {}
406
407impl<T: PartialEq> PartialEq for IdMap<T> {
408    fn eq(&self, other: &Self) -> bool {
409        self.ids == other.ids && self.ids
410            .iter()
411            .zip(&other.ids)
412            .all(|(l, r)| unsafe { self.values.get_unchecked(l) == other.values.get_unchecked(r) })
413    }
414}
415
416impl<T> Extend<T> for IdMap<T> {
417    #[inline]
418    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
419        for val in iter {
420            self.insert(val);
421        }
422    }
423}
424
425impl<T> FromIterator<T> for IdMap<T> {
426    #[inline]
427    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
428        let mut values = Vec::from_iter(iter);
429        unsafe { values.set_len(0) }
430        let space = values.capacity();
431        let ids = IdSet::new_filled(values.capacity());
432        IdMap {
433            values,
434            space,
435            ids,
436        }
437    }
438}
439
440impl<T> FromIterator<(Id, T)> for IdMap<T> {
441    #[inline]
442    fn from_iter<I: IntoIterator<Item = (Id, T)>>(iter: I) -> Self {
443        let iter = iter.into_iter();
444        let mut map = IdMap::with_capacity(iter.size_hint().0);
445        for (id, val) in iter {
446            map.insert_at(id, val);
447        }
448        map
449    }
450}
451
452impl<'a, T> IntoIterator for &'a IdMap<T> {
453    type Item = (Id, &'a T);
454    type IntoIter = Iter<'a, T>;
455
456    #[inline]
457    fn into_iter(self) -> Self::IntoIter {
458        self.iter()
459    }
460}
461
462impl<'a, T> IntoIterator for &'a mut IdMap<T> {
463    type Item = (Id, &'a mut T);
464    type IntoIter = IterMut<'a, T>;
465
466    #[inline]
467    fn into_iter(self) -> Self::IntoIter {
468        self.iter_mut()
469    }
470}
471
472impl<T> IntoIterator for IdMap<T> {
473    type Item = (Id, T);
474    type IntoIter = IntoIter<T>;
475
476    #[inline]
477    fn into_iter(self) -> Self::IntoIter {
478        self.into_iter()
479    }
480}
481
482impl<T> Index<Id> for IdMap<T> {
483    type Output = T;
484
485    #[inline]
486    fn index(&self, id: Id) -> &Self::Output {
487        assert!(self.ids.contains(id), "id {} out of bounds", id);
488        unsafe { self.values.get_unchecked(id) }
489    }
490}
491
492impl<T> IndexMut<Id> for IdMap<T> {
493    #[inline]
494    fn index_mut(&mut self, id: Id) -> &mut Self::Output {
495        assert!(self.ids.contains(id), "id {} out of bounds", id);
496        unsafe { self.values.get_unchecked_mut(id) }
497    }
498}
499
500#[derive(Clone, Debug)]
501/// An iterator over all ids, in increasing order.
502pub struct Ids<'a> {
503    ids: id_set::Iter<'a>,
504}
505
506impl<'a> Iterator for Ids<'a> {
507    type Item = Id;
508
509    #[inline]
510    fn next(&mut self) -> Option<Self::Item> {
511        self.ids.next()
512    }
513
514    #[inline]
515    fn size_hint(&self) -> (usize, Option<usize>) {
516        self.ids.size_hint()
517    }
518}
519
520impl<'a> ExactSizeIterator for Ids<'a> {
521    #[inline]
522    fn len(&self) -> usize {
523        self.ids.len()
524    }
525}
526
527#[derive(Debug)]
528/// An iterator over all values, in order of increasing id.
529pub struct Values<'a, T: 'a> {
530    ids: id_set::Iter<'a>,
531    values: *const T,
532}
533
534impl<'a, T: 'a> Iterator for Values<'a, T> {
535    type Item = &'a T;
536
537    #[inline]
538    fn next(&mut self) -> Option<Self::Item> {
539        self.ids.next().map(|id| unsafe { &*self.values.offset(id as isize) })
540    }
541
542    #[inline]
543    fn size_hint(&self) -> (usize, Option<usize>) {
544        self.ids.size_hint()
545    }
546}
547
548impl<'a, T: 'a> ExactSizeIterator for Values<'a, T> {
549    #[inline]
550    fn len(&self) -> usize {
551        self.ids.len()
552    }
553}
554
555impl<'a, T: 'a> Clone for Values<'a, T> {
556    #[inline]
557    fn clone(&self) -> Self {
558        Values {
559            ids: self.ids.clone(),
560            values: self.values,
561        }
562    }
563}
564
565#[derive(Debug)]
566/// A mutable iterator over all values, in order of increasing id.
567pub struct ValuesMut<'a, T: 'a> {
568    ids: id_set::Iter<'a>,
569    values: *mut T,
570}
571
572impl<'a, T: 'a> Iterator for ValuesMut<'a, T> {
573    type Item = &'a mut T;
574
575    #[inline]
576    fn next(&mut self) -> Option<Self::Item> {
577        self.ids.next().map(|id| unsafe { &mut *self.values.offset(id as isize) })
578    }
579
580    #[inline]
581    fn size_hint(&self) -> (usize, Option<usize>) {
582        self.ids.size_hint()
583    }
584}
585
586impl<'a, T: 'a> ExactSizeIterator for ValuesMut<'a, T> {
587    #[inline]
588    fn len(&self) -> usize {
589        self.ids.len()
590    }
591}
592
593#[derive(Debug)]
594/// An iterator over id-value pairs, in order of increasing id.
595pub struct Iter<'a, T: 'a> {
596    ids: id_set::Iter<'a>,
597    values: *const T,
598}
599
600impl<'a, T: 'a> Iterator for Iter<'a, T> {
601    type Item = (Id, &'a T);
602
603    #[inline]
604    fn next(&mut self) -> Option<Self::Item> {
605        self.ids.next().map(|id| (id, unsafe { &*self.values.offset(id as isize) }))
606    }
607
608    #[inline]
609    fn size_hint(&self) -> (usize, Option<usize>) {
610        self.ids.size_hint()
611    }
612}
613
614impl<'a, T: 'a> ExactSizeIterator for Iter<'a, T> {
615    #[inline]
616    fn len(&self) -> usize {
617        self.ids.len()
618    }
619}
620
621impl<'a, T: 'a> Clone for Iter<'a, T> {
622    #[inline]
623    fn clone(&self) -> Self {
624        Iter {
625            ids: self.ids.clone(),
626            values: self.values,
627        }
628    }
629}
630
631#[derive(Debug)]
632/// A mutable iterator over id-value pairs, in order of increasing id.
633pub struct IterMut<'a, T: 'a> {
634    ids: id_set::Iter<'a>,
635    values: *mut T,
636}
637
638impl<'a, T: 'a> Iterator for IterMut<'a, T> {
639    type Item = (Id, &'a mut T);
640
641    #[inline]
642    fn next(&mut self) -> Option<Self::Item> {
643        self.ids.next().map(|id| (id, unsafe { &mut *self.values.offset(id as isize) }))
644    }
645
646    #[inline]
647    fn size_hint(&self) -> (usize, Option<usize>) {
648        self.ids.size_hint()
649    }
650}
651
652impl<'a, T: 'a> ExactSizeIterator for IterMut<'a, T> {
653    #[inline]
654    fn len(&self) -> usize {
655        self.ids.len()
656    }
657}
658
659#[derive(Clone, Debug)]
660/// A consuming iterator over id-value pairs, in order of increasing id.
661pub struct IntoIter<T> {
662    ids: id_set::IntoIter,
663    values: Vec<T>,    
664}
665
666impl<T> Iterator for IntoIter<T> {
667    type Item = (Id, T);
668
669    #[inline]
670    fn next(&mut self) -> Option<Self::Item> {
671        self.ids.next().map(|id| (id, unsafe { ptr::read(self.values.get_unchecked(id)) }))
672    }
673
674    #[inline]
675    fn size_hint(&self) -> (usize, Option<usize>) {
676        self.ids.size_hint()
677    }
678}