Skip to content

Commit

Permalink
Keep track of number of set elements in map
Browse files Browse the repository at this point in the history
This allows much more efficient versions of len() and is_empty(), and
also enables ExactSizeIterator to be implemented to VecMap's iterators.

Fixes contain-rs#32
  • Loading branch information
jonhoo committed Apr 12, 2017
1 parent 9b8cb62 commit c4bd78a
Showing 1 changed file with 87 additions and 25 deletions.
112 changes: 87 additions & 25 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ use std::vec;
/// ```
#[cfg_attr(feature = "eders", derive(Serialize, Deserialize))]
pub struct VecMap<V> {
n: usize,
v: Vec<Option<V>>,
}

Expand Down Expand Up @@ -116,7 +117,7 @@ impl<V> VecMap<V> {
/// use vec_map::VecMap;
/// let mut map: VecMap<&str> = VecMap::new();
/// ```
pub fn new() -> Self { VecMap { v: vec![] } }
pub fn new() -> Self { VecMap { n: 0, v: vec![] } }

/// Creates an empty `VecMap` with space for at least `capacity`
/// elements before resizing.
Expand All @@ -128,7 +129,7 @@ impl<V> VecMap<V> {
/// let mut map: VecMap<&str> = VecMap::with_capacity(10);
/// ```
pub fn with_capacity(capacity: usize) -> Self {
VecMap { v: Vec::with_capacity(capacity) }
VecMap { n: 0, v: Vec::with_capacity(capacity) }
}

/// Returns the number of elements the `VecMap` can hold without
Expand Down Expand Up @@ -224,6 +225,8 @@ impl<V> VecMap<V> {
Iter {
front: 0,
back: self.v.len(),
n: self.n,
yielded: 0,
iter: self.v.iter()
}
}
Expand Down Expand Up @@ -254,6 +257,8 @@ impl<V> VecMap<V> {
IterMut {
front: 0,
back: self.v.len(),
n: self.n,
yielded: 0,
iter: self.v.iter_mut()
}
}
Expand Down Expand Up @@ -317,6 +322,7 @@ impl<V> VecMap<V> {

if at == 0 {
// Move all elements to other
// The swap will also fix .n
swap(self, &mut other);
return other
} else if at >= self.v.len() {
Expand All @@ -338,7 +344,16 @@ impl<V> VecMap<V> {
other.v.extend((0..start_index).map(|_| None));

// Move elements beginning with `start_index` from `self` into `other`
other.v.extend(self.v[start_index..].iter_mut().map(|el| el.take()));
let mut taken = 0;
other.v.extend(self.v[start_index..].iter_mut().map(|el| {
let el = el.take();
if el.is_some() {
taken += 1;
}
el
}));
other.n = taken;
self.n -= taken;

other
}
Expand Down Expand Up @@ -367,7 +382,10 @@ impl<V> VecMap<V> {
}
let filter: fn((usize, Option<V>)) -> Option<(usize, V)> = filter; // coerce to fn ptr

Drain { iter: self.v.drain(..).enumerate().filter_map(filter) }
Drain {
n: &mut self.n,
iter: self.v.drain(..).enumerate().filter_map(filter),
}
}

/// Returns the number of elements in the map.
Expand All @@ -383,7 +401,7 @@ impl<V> VecMap<V> {
/// assert_eq!(a.len(), 1);
/// ```
pub fn len(&self) -> usize {
self.v.iter().filter(|elt| elt.is_some()).count()
self.n
}

/// Returns true if the map contains no elements.
Expand All @@ -399,7 +417,7 @@ impl<V> VecMap<V> {
/// assert!(!a.is_empty());
/// ```
pub fn is_empty(&self) -> bool {
self.v.iter().all(|elt| elt.is_none())
self.n == 0
}

/// Clears the map, removing all key-value pairs.
Expand All @@ -414,7 +432,7 @@ impl<V> VecMap<V> {
/// a.clear();
/// assert!(a.is_empty());
/// ```
pub fn clear(&mut self) { self.v.clear() }
pub fn clear(&mut self) { self.n = 0; self.v.clear() }

/// Returns a reference to the value corresponding to the key.
///
Expand Down Expand Up @@ -502,7 +520,11 @@ impl<V> VecMap<V> {
if len <= key {
self.v.extend((0..key - len + 1).map(|_| None));
}
replace(&mut self.v[key], Some(value))
let was = replace(&mut self.v[key], Some(value));
if was.is_none() {
self.n += 1;
}
was
}

/// Removes a key from the map, returning the value at the key if the key
Expand All @@ -523,7 +545,11 @@ impl<V> VecMap<V> {
return None;
}
let result = &mut self.v[key];
result.take()
let was = result.take();
if was.is_some() {
self.n -= 1;
}
was
}

/// Gets the given key's corresponding entry in the map for in-place manipulation.
Expand Down Expand Up @@ -628,18 +654,19 @@ impl<'a, V> OccupiedEntry<'a, V> {
impl<V: Clone> Clone for VecMap<V> {
#[inline]
fn clone(&self) -> Self {
VecMap { v: self.v.clone() }
VecMap { n: self.n, v: self.v.clone() }
}

#[inline]
fn clone_from(&mut self, source: &Self) {
self.v.clone_from(&source.v);
self.n = source.n;
}
}

impl<V: PartialEq> PartialEq for VecMap<V> {
fn eq(&self, other: &Self) -> bool {
self.iter().eq(other.iter())
self.n == other.n && self.iter().eq(other.iter())
}
}

Expand Down Expand Up @@ -696,7 +723,11 @@ impl<T> IntoIterator for VecMap<T> {
/// assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]);
/// ```
fn into_iter(self) -> IntoIter<T> {
IntoIter { iter: self.v.into_iter().enumerate() }
IntoIter {
n: self.n,
yielded: 0,
iter: self.v.into_iter().enumerate()
}
}
}

Expand Down Expand Up @@ -778,6 +809,7 @@ macro_rules! iterator {
Some(x) => {
let index = self.front;
self.front += 1;
self.yielded += 1;
return Some((index, x));
},
None => {},
Expand All @@ -792,7 +824,7 @@ macro_rules! iterator {

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(self.back - self.front))
(self.n - self.yielded, Some(self.n - self.yielded))
}
}
}
Expand Down Expand Up @@ -828,6 +860,8 @@ macro_rules! double_ended_iterator {
pub struct Iter<'a, V: 'a> {
front: usize,
back: usize,
n: usize,
yielded: usize,
iter: slice::Iter<'a, Option<V>>
}

Expand All @@ -837,23 +871,29 @@ impl<'a, V> Clone for Iter<'a, V> {
Iter {
front: self.front,
back: self.back,
n: self.n,
yielded: self.yielded,
iter: self.iter.clone()
}
}
}

iterator! { impl Iter -> (usize, &'a V), as_ref }
impl<'a, V> ExactSizeIterator for Iter<'a, V> {}
double_ended_iterator! { impl Iter -> (usize, &'a V), as_ref }

/// An iterator over the key-value pairs of a map, with the
/// values being mutable.
pub struct IterMut<'a, V: 'a> {
front: usize,
back: usize,
n: usize,
yielded: usize,
iter: slice::IterMut<'a, Option<V>>
}

iterator! { impl IterMut -> (usize, &'a mut V), as_mut }
impl<'a, V> ExactSizeIterator for IterMut<'a, V> {}
double_ended_iterator! { impl IterMut -> (usize, &'a mut V), as_mut }

/// An iterator over the keys of a map.
Expand Down Expand Up @@ -886,11 +926,14 @@ impl<'a, V> Clone for Values<'a, V> {

/// A consuming iterator over the key-value pairs of a map.
pub struct IntoIter<V> {
n: usize,
yielded: usize,
iter: Enumerate<vec::IntoIter<Option<V>>>,
}

/// A draining iterator over the key-value pairs of a map.
pub struct Drain<'a, V: 'a> {
n: &'a mut usize,
iter: FilterMap<
Enumerate<vec::Drain<'a, Option<V>>>,
fn((usize, Option<V>)) -> Option<(usize, V)>>
Expand All @@ -899,10 +942,18 @@ pub struct Drain<'a, V: 'a> {
impl<'a, V> Iterator for Drain<'a, V> {
type Item = (usize, V);

fn next(&mut self) -> Option<(usize, V)> { self.iter.next() }
fn next(&mut self) -> Option<(usize, V)> {
let next = self.iter.next();
if next.is_some() {
*self.n -= 1;
}
next
}
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}

impl<'a, V> ExactSizeIterator for Drain<'a, V> {}

impl<'a, V> DoubleEndedIterator for Drain<'a, V> {
fn next_back(&mut self) -> Option<(usize, V)> { self.iter.next_back() }
}
Expand All @@ -914,6 +965,8 @@ impl<'a, V> Iterator for Keys<'a, V> {
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}

impl<'a, V> ExactSizeIterator for Keys<'a, V> {}

impl<'a, V> DoubleEndedIterator for Keys<'a, V> {
fn next_back(&mut self) -> Option<usize> { self.iter.next_back().map(|e| e.0) }
}
Expand All @@ -925,6 +978,8 @@ impl<'a, V> Iterator for Values<'a, V> {
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}

impl<'a, V> ExactSizeIterator for Values<'a, V> {}

impl<'a, V> DoubleEndedIterator for Values<'a, V> {
fn next_back(&mut self) -> Option<(&'a V)> { self.iter.next_back().map(|e| e.1) }
}
Expand All @@ -936,15 +991,22 @@ impl<V> Iterator for IntoIter<V> {
loop {
match self.iter.next() {
None => return None,
Some((i, Some(value))) => return Some((i, value)),
Some((i, Some(value))) => {
self.yielded += 1;
return Some((i, value))
},
_ => {}
}
}
}

fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
fn size_hint(&self) -> (usize, Option<usize>) {
(self.n - self.yielded, Some(self.n - self.yielded))
}
}

impl<V> ExactSizeIterator for IntoIter<V> {}

impl<V> DoubleEndedIterator for IntoIter<V> {
fn next_back(&mut self) -> Option<(usize, V)> {
loop {
Expand Down Expand Up @@ -1071,15 +1133,15 @@ mod test {
assert!(m.insert(10, 11).is_none());

let mut it = m.iter();
assert_eq!(it.size_hint(), (0, Some(11)));
assert_eq!(it.size_hint(), (5, Some(5)));
assert_eq!(it.next().unwrap(), (0, &1));
assert_eq!(it.size_hint(), (0, Some(10)));
assert_eq!(it.size_hint(), (4, Some(4)));
assert_eq!(it.next().unwrap(), (1, &2));
assert_eq!(it.size_hint(), (0, Some(9)));
assert_eq!(it.size_hint(), (3, Some(3)));
assert_eq!(it.next().unwrap(), (3, &5));
assert_eq!(it.size_hint(), (0, Some(7)));
assert_eq!(it.size_hint(), (2, Some(2)));
assert_eq!(it.next().unwrap(), (6, &10));
assert_eq!(it.size_hint(), (0, Some(4)));
assert_eq!(it.size_hint(), (1, Some(1)));
assert_eq!(it.next().unwrap(), (10, &11));
assert_eq!(it.size_hint(), (0, Some(0)));
assert!(it.next().is_none());
Expand All @@ -1095,10 +1157,10 @@ mod test {
assert!(m.insert(6, 10).is_none());
assert!(m.insert(10, 11).is_none());

assert_eq!(m.iter().size_hint(), (0, Some(11)));
assert_eq!(m.iter().rev().size_hint(), (0, Some(11)));
assert_eq!(m.iter_mut().size_hint(), (0, Some(11)));
assert_eq!(m.iter_mut().rev().size_hint(), (0, Some(11)));
assert_eq!(m.iter().size_hint(), (5, Some(5)));
assert_eq!(m.iter().rev().size_hint(), (5, Some(5)));
assert_eq!(m.iter_mut().size_hint(), (5, Some(5)));
assert_eq!(m.iter_mut().rev().size_hint(), (5, Some(5)));
}

#[test]
Expand Down

0 comments on commit c4bd78a

Please sign in to comment.