auto merge of #7934 : sfackler/rust/smallintset, r=alexcrichton
SmallIntSet is equivalent to BitvSet but with 64 times the memory overhead. There's no reason for it to exist. SmallIntSet's overhead should really only be 8 times, but for some reason, `sys::size_of::<Option<()>>() == 8`, not 1.
This commit is contained in:
commit
dfdb72dbbe
@ -15,8 +15,6 @@
|
||||
|
||||
#[allow(missing_doc)];
|
||||
|
||||
|
||||
use std::cmp;
|
||||
use std::iterator::{Iterator, IteratorUtil, EnumerateIterator, FilterMapIterator, InvertIterator};
|
||||
use std::uint;
|
||||
use std::util::replace;
|
||||
@ -309,155 +307,6 @@ double_ended_iterator!(impl SmallIntMapMutIterator -> (uint, &'self mut T), get_
|
||||
pub type SmallIntMapMutRevIterator<'self, T> = InvertIterator<(uint, &'self mut T),
|
||||
SmallIntMapMutIterator<'self, T>>;
|
||||
|
||||
|
||||
/// A set implemented on top of the SmallIntMap type. This set is always a set
|
||||
/// of integers, and the space requirements are on the order of the highest
|
||||
/// valued integer in the set.
|
||||
pub struct SmallIntSet {
|
||||
priv map: SmallIntMap<()>
|
||||
}
|
||||
|
||||
impl Container for SmallIntSet {
|
||||
/// Return the number of elements in the map
|
||||
fn len(&self) -> uint {
|
||||
self.map.len()
|
||||
}
|
||||
|
||||
/// Return true if the map contains no elements
|
||||
fn is_empty(&self) -> bool { self.len() == 0 }
|
||||
}
|
||||
|
||||
impl Mutable for SmallIntSet {
|
||||
/// Clear the map, removing all key-value pairs.
|
||||
fn clear(&mut self) { self.map.clear() }
|
||||
}
|
||||
|
||||
impl Set<uint> for SmallIntSet {
|
||||
/// Return true if the set contains a value
|
||||
fn contains(&self, value: &uint) -> bool { self.map.contains_key(value) }
|
||||
|
||||
/// Return true if the set has no elements in common with `other`.
|
||||
/// This is equivalent to checking for an empty uintersection.
|
||||
fn is_disjoint(&self, other: &SmallIntSet) -> bool {
|
||||
for self.each |v| { if other.contains(v) { return false } }
|
||||
true
|
||||
}
|
||||
|
||||
/// Return true if the set is a subset of another
|
||||
fn is_subset(&self, other: &SmallIntSet) -> bool {
|
||||
for self.each |v| { if !other.contains(v) { return false } }
|
||||
true
|
||||
}
|
||||
|
||||
/// Return true if the set is a superset of another
|
||||
fn is_superset(&self, other: &SmallIntSet) -> bool {
|
||||
other.is_subset(self)
|
||||
}
|
||||
|
||||
/// Visit the values representing the difference
|
||||
fn difference(&self, other: &SmallIntSet, f: &fn(&uint) -> bool) -> bool {
|
||||
self.each(|v| other.contains(v) || f(v))
|
||||
}
|
||||
|
||||
/// Visit the values representing the symmetric difference
|
||||
fn symmetric_difference(&self,
|
||||
other: &SmallIntSet,
|
||||
f: &fn(&uint) -> bool) -> bool {
|
||||
let len = cmp::max(self.map.v.len() ,other.map.v.len());
|
||||
|
||||
for uint::range(0, len) |i| {
|
||||
if self.contains(&i) ^ other.contains(&i) {
|
||||
if !f(&i) { return false; }
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Visit the values representing the uintersection
|
||||
fn intersection(&self, other: &SmallIntSet, f: &fn(&uint) -> bool) -> bool {
|
||||
self.each(|v| !other.contains(v) || f(v))
|
||||
}
|
||||
|
||||
/// Visit the values representing the union
|
||||
fn union(&self, other: &SmallIntSet, f: &fn(&uint) -> bool) -> bool {
|
||||
let len = cmp::max(self.map.v.len() ,other.map.v.len());
|
||||
|
||||
for uint::range(0, len) |i| {
|
||||
if self.contains(&i) || other.contains(&i) {
|
||||
if !f(&i) { return false; }
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
impl MutableSet<uint> for SmallIntSet {
|
||||
/// Add a value to the set. Return true if the value was not already
|
||||
/// present in the set.
|
||||
fn insert(&mut self, value: uint) -> bool { self.map.insert(value, ()) }
|
||||
|
||||
/// Remove a value from the set. Return true if the value was
|
||||
/// present in the set.
|
||||
fn remove(&mut self, value: &uint) -> bool { self.map.remove(value) }
|
||||
}
|
||||
|
||||
impl SmallIntSet {
|
||||
/// Create an empty SmallIntSet
|
||||
pub fn new() -> SmallIntSet { SmallIntSet{map: SmallIntMap::new()} }
|
||||
|
||||
/// Visit all values in order
|
||||
pub fn each(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key(f) }
|
||||
|
||||
/// An iterator visiting all set members in ascending order.
|
||||
/// Iterator element type is uint
|
||||
pub fn iter<'r>(&'r self) -> SmallIntSetIterator<'r> {
|
||||
SmallIntSetIterator {
|
||||
iter: self.map.iter()
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator visiting all set members in descending order.
|
||||
/// Iterator element type is uint
|
||||
pub fn rev_iter<'r>(&'r mut self) -> SmallIntSetRevIterator<'r> {
|
||||
self.iter().invert()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub struct SmallIntSetIterator<'self> {
|
||||
priv iter: SmallIntMapIterator<'self, ()>
|
||||
}
|
||||
|
||||
impl<'self> Iterator<uint> for SmallIntSetIterator<'self> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<uint> {
|
||||
let next_opt = self.iter.next();
|
||||
match next_opt {
|
||||
None => { None }
|
||||
Some((idx, _)) => { Some(idx) }
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||
self.iter.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self> DoubleEndedIterator<uint> for SmallIntSetIterator<'self> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<uint> {
|
||||
let next_opt = self.iter.next_back();
|
||||
match next_opt {
|
||||
None => { None }
|
||||
Some((idx, _)) => { Some(idx) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type SmallIntSetRevIterator<'self> = InvertIterator<uint, SmallIntSetIterator<'self>>;
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_map {
|
||||
|
||||
@ -732,221 +581,3 @@ mod bench {
|
||||
find_seq_n(10_000, &mut m, bh);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_set {
|
||||
|
||||
use super::SmallIntSet;
|
||||
|
||||
#[test]
|
||||
fn test_disjoint() {
|
||||
let mut xs = SmallIntSet::new();
|
||||
let mut ys = SmallIntSet::new();
|
||||
assert!(xs.is_disjoint(&ys));
|
||||
assert!(ys.is_disjoint(&xs));
|
||||
assert!(xs.insert(5));
|
||||
assert!(ys.insert(11));
|
||||
assert!(xs.is_disjoint(&ys));
|
||||
assert!(ys.is_disjoint(&xs));
|
||||
assert!(xs.insert(7));
|
||||
assert!(xs.insert(19));
|
||||
assert!(xs.insert(4));
|
||||
assert!(ys.insert(2));
|
||||
assert!(xs.is_disjoint(&ys));
|
||||
assert!(ys.is_disjoint(&xs));
|
||||
assert!(ys.insert(7));
|
||||
assert!(!xs.is_disjoint(&ys));
|
||||
assert!(!ys.is_disjoint(&xs));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subset_and_superset() {
|
||||
let mut a = SmallIntSet::new();
|
||||
assert!(a.insert(0));
|
||||
assert!(a.insert(5));
|
||||
assert!(a.insert(11));
|
||||
assert!(a.insert(7));
|
||||
|
||||
let mut b = SmallIntSet::new();
|
||||
assert!(b.insert(0));
|
||||
assert!(b.insert(7));
|
||||
assert!(b.insert(19));
|
||||
assert!(b.insert(250));
|
||||
assert!(b.insert(11));
|
||||
assert!(b.insert(200));
|
||||
|
||||
assert!(!a.is_subset(&b));
|
||||
assert!(!a.is_superset(&b));
|
||||
assert!(!b.is_subset(&a));
|
||||
assert!(!b.is_superset(&a));
|
||||
|
||||
assert!(b.insert(5));
|
||||
|
||||
assert!(a.is_subset(&b));
|
||||
assert!(!a.is_superset(&b));
|
||||
assert!(!b.is_subset(&a));
|
||||
assert!(b.is_superset(&a));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intersection() {
|
||||
let mut a = SmallIntSet::new();
|
||||
let mut b = SmallIntSet::new();
|
||||
|
||||
assert!(a.insert(11));
|
||||
assert!(a.insert(1));
|
||||
assert!(a.insert(3));
|
||||
assert!(a.insert(77));
|
||||
assert!(a.insert(103));
|
||||
assert!(a.insert(5));
|
||||
|
||||
assert!(b.insert(2));
|
||||
assert!(b.insert(11));
|
||||
assert!(b.insert(77));
|
||||
assert!(b.insert(5));
|
||||
assert!(b.insert(3));
|
||||
|
||||
let mut i = 0;
|
||||
let expected = [3, 5, 11, 77];
|
||||
for a.intersection(&b) |x| {
|
||||
assert!(expected.contains(x));
|
||||
i += 1
|
||||
}
|
||||
assert_eq!(i, expected.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_difference() {
|
||||
let mut a = SmallIntSet::new();
|
||||
let mut b = SmallIntSet::new();
|
||||
|
||||
assert!(a.insert(1));
|
||||
assert!(a.insert(3));
|
||||
assert!(a.insert(5));
|
||||
assert!(a.insert(9));
|
||||
assert!(a.insert(11));
|
||||
|
||||
assert!(b.insert(3));
|
||||
assert!(b.insert(9));
|
||||
|
||||
let mut i = 0;
|
||||
let expected = [1, 5, 11];
|
||||
for a.difference(&b) |x| {
|
||||
assert!(expected.contains(x));
|
||||
i += 1
|
||||
}
|
||||
assert_eq!(i, expected.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symmetric_difference() {
|
||||
let mut a = SmallIntSet::new();
|
||||
let mut b = SmallIntSet::new();
|
||||
|
||||
assert!(a.insert(1));
|
||||
assert!(a.insert(3));
|
||||
assert!(a.insert(5));
|
||||
assert!(a.insert(9));
|
||||
assert!(a.insert(11));
|
||||
|
||||
assert!(b.insert(3));
|
||||
assert!(b.insert(9));
|
||||
assert!(b.insert(14));
|
||||
assert!(b.insert(22));
|
||||
|
||||
let mut i = 0;
|
||||
let expected = [1, 5, 11, 14, 22];
|
||||
for a.symmetric_difference(&b) |x| {
|
||||
assert!(expected.contains(x));
|
||||
i += 1
|
||||
}
|
||||
assert_eq!(i, expected.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_union() {
|
||||
let mut a = SmallIntSet::new();
|
||||
let mut b = SmallIntSet::new();
|
||||
|
||||
assert!(a.insert(1));
|
||||
assert!(a.insert(3));
|
||||
assert!(a.insert(5));
|
||||
assert!(a.insert(9));
|
||||
assert!(a.insert(11));
|
||||
assert!(a.insert(16));
|
||||
assert!(a.insert(19));
|
||||
assert!(a.insert(24));
|
||||
|
||||
assert!(b.insert(1));
|
||||
assert!(b.insert(5));
|
||||
assert!(b.insert(9));
|
||||
assert!(b.insert(13));
|
||||
assert!(b.insert(19));
|
||||
|
||||
let mut i = 0;
|
||||
let expected = [1, 3, 5, 9, 11, 13, 16, 19, 24];
|
||||
for a.union(&b) |x| {
|
||||
assert!(expected.contains(x));
|
||||
i += 1
|
||||
}
|
||||
assert_eq!(i, expected.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator() {
|
||||
let mut a = SmallIntSet::new();
|
||||
|
||||
assert!(a.insert(0));
|
||||
assert!(a.insert(1));
|
||||
assert!(a.insert(3));
|
||||
assert!(a.insert(6));
|
||||
assert!(a.insert(10));
|
||||
|
||||
let mut it = a.iter();
|
||||
assert_eq!(it.size_hint(), (0, Some(11)));
|
||||
assert_eq!(it.next().unwrap(), 0);
|
||||
assert_eq!(it.size_hint(), (0, Some(10)));
|
||||
assert_eq!(it.next().unwrap(), 1);
|
||||
assert_eq!(it.size_hint(), (0, Some(9)));
|
||||
assert_eq!(it.next().unwrap(), 3);
|
||||
assert_eq!(it.size_hint(), (0, Some(7)));
|
||||
assert_eq!(it.next().unwrap(), 6);
|
||||
assert_eq!(it.size_hint(), (0, Some(4)));
|
||||
assert_eq!(it.next().unwrap(), 10);
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_size_hints() {
|
||||
let mut a = SmallIntSet::new();
|
||||
|
||||
assert!(a.insert(0));
|
||||
assert!(a.insert(1));
|
||||
assert!(a.insert(3));
|
||||
assert!(a.insert(6));
|
||||
assert!(a.insert(10));
|
||||
|
||||
assert_eq!(a.iter().size_hint(), (0, Some(11)));
|
||||
assert_eq!(a.rev_iter().size_hint(), (0, Some(11)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rev_iterator() {
|
||||
let mut a = SmallIntSet::new();
|
||||
|
||||
assert!(a.insert(0));
|
||||
assert!(a.insert(1));
|
||||
assert!(a.insert(3));
|
||||
assert!(a.insert(6));
|
||||
assert!(a.insert(10));
|
||||
|
||||
let mut it = a.rev_iter();
|
||||
assert_eq!(it.next().unwrap(), 10);
|
||||
assert_eq!(it.next().unwrap(), 6);
|
||||
assert_eq!(it.next().unwrap(), 3);
|
||||
assert_eq!(it.next().unwrap(), 1);
|
||||
assert_eq!(it.next().unwrap(), 0);
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user