diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 80f1f05961a5d..6b1509cf15d7a 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -127,6 +127,20 @@ totalord_impl!(uint) totalord_impl!(char) +impl<'self, T: TotalEq> TotalEq for &'self T { + #[inline(always)] + fn equals(&self, other: & &'self T) -> bool { + (**self).equals(*other) + } +} + +impl<'self, T: TotalOrd> TotalOrd for &'self T { + #[inline(always)] + fn cmp(&self, other: & &'self T) -> Ordering { + (**self).cmp(*other) + } +} + pub fn cmp2( a1: &A, b1: &B, a2: &A, b2: &B) -> Ordering diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 5e95485b27360..5f467d990c0b6 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -18,6 +18,7 @@ implementing the `Iterator` trait. */ use prelude::*; +use util; pub trait Iterator { /// Advance the iterator and return the next value. Return `None` when the end is reached. @@ -39,9 +40,17 @@ pub trait IteratorUtil { fn take_while<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, Self>; fn skip(self, n: uint) -> SkipIterator; fn take(self, n: uint) -> TakeIterator; + fn scan<'r, St, B>(self, initial_state: St, f: &'r fn(&mut St, A) -> Option) -> ScanIterator<'r, A, B, Self, St>; fn advance(&mut self, f: &fn(A) -> bool); + + // Ordered iterators + // FIXME: #5898: shouldn't have the 'i' suffix + fn intersecti>(self, other: U) -> Intersect; + fn unioni>(self, other: U) -> Union; + fn xori>(self, other: U) -> Xor; + fn differencei>(self, other: U) -> Difference; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -113,6 +122,52 @@ impl> IteratorUtil for T { } } } + + /// Returns an interator which will iterate over the intersection of `self` + /// and `other`. This requires that the two iterators iterate over their + /// values in ascending order. + #[inline(always)] + fn intersecti>(self, mut other: U) -> Intersect { + let mut self = self; + let a = self.next(); + let b = other.next(); + Intersect{ a: a, b: b, i1: self, i2: other } + } + + /// Returns an interator which will iterate over the union of `self` and + /// `other`. This requires that the two iterators iterate over their values + /// in ascending order. + #[inline(always)] + fn unioni>(self, mut other: U) -> Union { + let mut self = self; + let a = self.next(); + let b = other.next(); + Union{ a: a, b: b, i1: self, i2: other } + } + + /// Returns an interator which will iterate over the symmetric difference of + /// `self` and `other`, or all values which are present in one, but not both + /// iterators. This requires that the two iterators iterate over their + /// values in ascending order. + #[inline(always)] + fn xori>(self, mut other: U) -> Xor { + let mut self = self; + let a = self.next(); + let b = other.next(); + Xor{ a: a, b: b, i1: self, i2: other } + } + + /// Returns an interator which will iterate over the difference of `self` + /// and `other`, or all values which are present in `self`, but not in + /// `other` iterators. This requires that the two iterators iterate over + /// their value in ascending order. + #[inline(always)] + fn differencei>(self, mut other: U) -> Difference { + let mut self = self; + let a = self.next(); + let b = other.next(); + Difference{ a: a, b: b, i1: self, i2: other } + } } pub struct ChainIterator { @@ -348,6 +403,137 @@ impl<'self, A, St> Iterator for UnfoldrIterator<'self, A, St> { } } +pub struct Intersect { + priv i1: T, + priv i2: U, + priv a: Option, + priv b: Option, +} + +impl, U: Iterator> Iterator for + Intersect +{ + #[inline] + fn next(&mut self) -> Option { + loop { + let cmp = match (&self.a, &self.b) { + (&Some(ref a), &Some(ref b)) => a.cmp(b), + _ => return None + }; + + match cmp { + Less => { util::replace(&mut self.a, self.i1.next()); } + Greater => { util::replace(&mut self.b, self.i2.next()); } + Equal => { + util::replace(&mut self.a, self.i1.next()); + return util::replace(&mut self.b, self.i2.next()); + } + } + } + } +} + +pub struct Union { + priv i1: T, + priv i2: U, + priv a: Option, + priv b: Option, +} + +impl, U: Iterator> Iterator for Union +{ + #[inline] + fn next(&mut self) -> Option { + if self.a.is_none() && self.b.is_none() { + return None; + } else if self.a.is_none() { + return util::replace(&mut self.b, self.i2.next()); + } else if self.b.is_none() { + return util::replace(&mut self.a, self.i1.next()); + } + let cmp = match (&self.a, &self.b) { + (&Some(ref a), &Some(ref b)) => a.cmp(b), + _ => fail!() + }; + match cmp { + Less => { return util::replace(&mut self.a, self.i1.next()); } + Greater => { return util::replace(&mut self.b, self.i2.next()); } + Equal => { + util::replace(&mut self.b, self.i2.next()); + return util::replace(&mut self.a, self.i1.next()); + } + } + } +} + +pub struct Xor { + priv i1: T, + priv i2: U, + priv a: Option, + priv b: Option, +} + +impl, U: Iterator> Iterator for Xor { + #[inline] + fn next(&mut self) -> Option { + loop { + if self.a.is_none() && self.b.is_none() { + return None; + } else if self.a.is_none() { + return util::replace(&mut self.b, self.i2.next()); + } else if self.b.is_none() { + return util::replace(&mut self.a, self.i1.next()); + } + let cmp = match (&self.a, &self.b) { + (&Some(ref a), &Some(ref b)) => a.cmp(b), + _ => fail!() + }; + match cmp { + Less => { return util::replace(&mut self.a, self.i1.next()); } + Greater => { return util::replace(&mut self.b, self.i2.next()); } + Equal => { + util::replace(&mut self.a, self.i1.next()); + util::replace(&mut self.b, self.i2.next()); + } + } + } + } +} + +pub struct Difference { + priv i1: T, + priv i2: U, + priv a: Option, + priv b: Option, +} + +impl, U: Iterator> Iterator for + Difference +{ + #[inline] + fn next(&mut self) -> Option { + loop { + if self.a.is_none() { + return None; + } else if self.b.is_none() { + return util::replace(&mut self.a, self.i1.next()); + } + let cmp = match (&self.a, &self.b) { + (&Some(ref a), &Some(ref b)) => a.cmp(b), + _ => fail!() + }; + match cmp { + Less => { return util::replace(&mut self.a, self.i1.next()); } + Greater => { util::replace(&mut self.b, self.i2.next()); } + Equal => { + util::replace(&mut self.b, self.i2.next()); + util::replace(&mut self.a, self.i1.next()); + } + } + } + } +} + /// An infinite iterator starting at `start` and advancing by `step` with each iteration pub struct Counter { state: A, @@ -370,6 +556,54 @@ impl + Clone> Iterator for Counter { } } +/// An interator which will iterate over a binary search tree. This is +/// parameterized over functions which take a node and return the left and right +/// children. It is required that the nodes form a tree which is a binary search +/// tree +pub struct BSTIterator<'self, N, T> { + priv f: &'self fn(&'self N) -> T, + priv left: &'self fn(&'self N) -> &'self Option<~N>, + priv right: &'self fn(&'self N) -> &'self Option<~N>, + priv stack: ~[&'self ~N], + priv node: &'self Option<~N>, +} + +pub impl<'self, N, T> BSTIterator<'self, N, T> { + /// Creates a new iterator given the root node of a tree. The provided + /// functions are used for yielding iterator values and acquiring the left + /// and right children. + #[inline(always)] + fn new<'a>(root: &'a Option<~N>, + f: &'a fn(&'a N) -> T, + left: &'a fn(&'a N) -> &'a Option<~N>, + right: &'a fn(&'a N) -> &'a Option<~N>) -> BSTIterator<'a, N, T> + { + BSTIterator{ f: f, stack: ~[], node: root, left: left, right: right } + } +} + +impl<'self, N, T> Iterator for BSTIterator<'self, N, T> { + /// Advance the iterator to the next node (in order) and return a + /// tuple with a reference to the key and value. If there are no + /// more nodes, return `None`. + fn next(&mut self) -> Option { + while !self.stack.is_empty() || self.node.is_some() { + match *self.node { + Some(ref x) => { + self.stack.push(x); + self.node = (self.left)(*x); + } + None => { + let res = self.stack.pop(); + self.node = (self.right)(*res); + return Some((self.f)(*res)); + } + } + } + None + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index 461fb61ed5665..fe0f599b1a164 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -72,7 +72,7 @@ pub impl SmallBitv { } #[inline(always)] - fn equals(&self, b: &SmallBitv, nbits: uint) -> bool { + fn iseq(&self, b: &SmallBitv, nbits: uint) -> bool { let mask = small_mask(nbits); mask & self.bits == mask & b.bits } @@ -193,7 +193,7 @@ pub impl BigBitv { } #[inline(always)] - fn equals(&self, b: &BigBitv, nbits: uint) -> bool { + fn iseq(&self, b: &BigBitv, nbits: uint) -> bool { let len = b.storage.len(); for uint::iterate(0, len) |i| { let mask = big_mask(nbits, i); @@ -327,11 +327,11 @@ pub impl Bitv { if self.nbits != v1.nbits { return false; } match self.rep { Small(ref b) => match v1.rep { - Small(ref b1) => b.equals(*b1, self.nbits), + Small(ref b1) => b.iseq(*b1, self.nbits), _ => false }, Big(ref s) => match v1.rep { - Big(ref s1) => s.equals(*s1, self.nbits), + Big(ref s1) => s.iseq(*s1, self.nbits), Small(_) => return false } } diff --git a/src/libstd/splay.rs b/src/libstd/splay.rs new file mode 100644 index 0000000000000..1a98f8221bf4d --- /dev/null +++ b/src/libstd/splay.rs @@ -0,0 +1,577 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Contains an implementation of splay trees where each node has a key/value +//! pair to be used in maps and sets. The only requirement is that the key must +//! implement the TotalOrd trait. + +use core::iterator::*; +use core::util; + +/// The implementation of this splay tree is largely based on the java code at: +/// https://github.com/cpdomina/SplaySplayMap. This version of splaying is a +/// top-down splay operation. +pub struct SplayMap { + priv root: Option<~Node>, + priv size: uint, +} + +pub struct SplaySet { + priv map: SplayMap +} + +struct Node { + key: K, + value: V, + left: Option<~Node>, + right: Option<~Node>, +} + +pub impl SplayMap { + fn new() -> SplayMap { + SplayMap{ root: None, size: 0 } + } + + /// Performs a splay operation on the tree, moving a key to the root, or one + /// of the closest values to the key to the root. + fn splay(&mut self, key: &K) { + let mut root = util::replace(&mut self.root, None).unwrap(); + let mut newleft = None; + let mut newright = None; + + // Yes, these are backwards, that's intentional. + root = root.splay(key, &mut newright, &mut newleft); + + root.left = newright; + root.right = newleft; + self.root = Some(root); + } + + /// Get a lazy iterator over the key-value pairs in the map. + /// Requires that it be frozen (immutable). + fn iter<'a>(&'a self) -> BSTIterator<'a, Node, (&'a K, &'a V)> { + BSTIterator::new(&self.root, + |n| (&n.key, &n.value), + |n| &n.left, + |n| &n.right) + } +} + +impl Container for SplayMap { + fn len(&const self) -> uint { self.size } + fn is_empty(&const self) -> bool { self.len() == 0 } +} + +impl Mutable for SplayMap { + fn clear(&mut self) { + self.root = None; + self.size = 0; + } +} + +impl Map for SplayMap { + /// Return true if the map contains a value for the specified key + #[inline(always)] + fn contains_key(&self, key: &K) -> bool { + self.find(key).is_some() + } + + /// Visit all values in order + #[inline(always)] + fn each<'a>(&'a self, f: &fn(&K, &'a V) -> bool) { + for self.root.each |n| { + n.each(f); + } + } + + /// Iterate over the map and mutate the contained values + #[inline(always)] + fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) { + match self.root { + None => {} + Some(ref mut node) => node.each_mut(f) + } + } + + /// Visit all keys in order + #[inline(always)] + fn each_key(&self, f: &fn(&K) -> bool) { self.each(|k, _| f(k)) } + + /// Visit all values in order + #[inline(always)] + fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) { + self.each(|_, v| f(v)) + } + + /// Insert a key-value pair into the map. An existing value for a + /// key is replaced by the new value. Return true if the key did + /// not already exist in the map. + #[inline(always)] + fn insert(&mut self, key: K, value: V) -> bool { + self.swap(key, value).is_none() + } + + /// Insert a key-value pair from the map. If the key already had a value + /// present in the map, that value is returned. Otherwise None is returned. + fn swap(&mut self, key: K, value: V) -> Option { + if self.root.is_none() { + self.root = Some(Node::new(key, value)); + self.size += 1; + return None; + } + + self.splay(&key); + let mut root = util::replace(&mut self.root, None).unwrap(); + + match key.cmp(&root.key) { + Equal => { + let ret = Some(util::replace(&mut root.value, value)); + self.root = Some(root); + return ret; + } + Less => { + let mut me = Node::new(key, value); + me.left = util::replace(&mut root.left, None); + me.right = Some(root); + self.root = Some(me); + } + Greater => { + let mut me = Node::new(key, value); + me.right = util::replace(&mut root.right, None); + me.left = Some(root); + self.root = Some(me); + } + } + + self.size += 1; + return None; + } + + /// Remove a key-value pair from the map. Return true if the key + /// was present in the map, otherwise false. + #[inline(always)] + fn remove(&mut self, key: &K) -> bool { + self.pop(key).is_some() + } + + /// Removes a key from the map, returning the value at the key if the key + /// was previously in the map. + fn pop(&mut self, key: &K) -> Option { + if self.root.is_none() { + return None; + } + + self.splay(key); + let root = util::replace(&mut self.root, None).unwrap(); + if !key.equals(&root.key) { + self.root = Some(root); + return None; + } + + let (value, left, right) = match root { + ~Node {left, right, value, _} => (value, left, right) + }; + + if left.is_none() { + self.root = right; + } else { + self.root = left; + self.splay(key); + match self.root { + Some(ref mut node) => { node.right = right; } + None => fail!() + } + } + + self.size -= 1; + return Some(value); + } + + /// Return a mutable reference to the value corresponding to the key + fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> { + if self.root.is_none() { + return None; + } + + self.splay(key); + match self.root { + None => fail!(), + Some(ref mut r) => { + if key.equals(&r.key) { + return Some(&mut r.value); + } + return None; + } + } + } + + /// Return a reference to the value corresponding to the key + fn find<'a>(&'a self, key: &K) -> Option<&'a V> { + // Splay trees are self-modifying, so they can't exactly operate with + // the immutable self given by the Map interface for this method. It can + // be guaranteed, however, that the callers of this method are not + // modifying the tree, they may just be rotating it. Each node is a + // pointer on the heap, so we know that none of the pointers inside + // these nodes (the value returned from this function) will be moving. + // + // With this in mind, we can unsafely use a mutable version of this tree + // to invoke the splay operation and return a pointer to the inside of + // one of the nodes (the pointer won't be deallocated or moved). + unsafe { + let self = cast::transmute_mut(self); + match self.find_mut(key) { + None => None, + Some(ptr) => Some(cast::transmute_immut(ptr)) + } + } + } +} + +impl Container for SplaySet { + #[inline(always)] + fn len(&const self) -> uint { self.map.len() } + #[inline(always)] + fn is_empty(&const self) -> bool { self.map.is_empty() } +} + +impl Mutable for SplaySet { + #[inline(always)] + fn clear(&mut self) { self.map.clear() } +} + +impl Set for SplaySet { + /// Add a value to the set. Return true if the value was not already + /// present in the set. + #[inline(always)] + fn insert(&mut self, t: T) -> bool { self.map.insert(t, ()) } + + /// Return true if the set contains a value + #[inline(always)] + fn contains(&self, t: &T) -> bool { self.map.contains_key(t) } + + /// Remove a value from the set. Return true if the value was + /// present in the set. + #[inline(always)] + fn remove(&mut self, t: &T) -> bool { self.map.remove(t) } + + /// Return true if the set has no elements in common with `other`. + /// This is equivalent to checking for an empty intersection. + fn is_disjoint(&self, other: &SplaySet) -> bool { + for self.intersection(other) |_| { + return false; + } + return true; + } + + /// Return true if the set is a subset of another + fn is_subset(&self, other: &SplaySet) -> bool { + let mut amt = 0; + for self.intersection(other) |_| { + amt += 1; + } + return amt == self.len(); + } + + /// Return true if the set is a superset of another + fn is_superset(&self, other: &SplaySet) -> bool { + other.is_subset(self) + } + + /// Visit the values (in-order) representing the difference + fn difference(&self, other: &SplaySet, f: &fn(&T) -> bool) { + let mut it = self.iter(); + let mut it = it.differencei(other.iter()); + it.advance(f) + } + + /// Visit the values (in-order) representing the union + fn union(&self, other: &SplaySet, f: &fn(&T) -> bool) { + let mut it = self.iter(); + let mut it = it.unioni(other.iter()); + it.advance(f) + } + + /// Visit the values (in-order) representing the intersection + fn intersection(&self, other: &SplaySet, f: &fn(&T) -> bool) { + let mut it = self.iter(); + let mut it = it.intersecti(other.iter()); + it.advance(f) + } + + /// Visit the values (in-order) representing the symmetric difference + fn symmetric_difference(&self, other: &SplaySet, f: &fn(&T) -> bool) { + let mut it = self.iter(); + let mut it = it.xori(other.iter()); + it.advance(f) + } +} + +pub impl SplaySet { + /// Creates a new empty set + pub fn new() -> SplaySet { + SplaySet { map: SplayMap::new() } + } + + /// Get a lazy iterator over the values in the set. + /// Requires that it be frozen (immutable). + #[inline(always)] + fn iter<'a>(&'a self) -> + MapIterator<(&'a T, &'a ()), &'a T, + BSTIterator<'a, Node, (&'a T, &'a ())>> // ouch + { + self.map.iter().transform(|(a, _)| a) + } +} + +impl Node { + fn new(k: K, v: V) -> ~Node { + ~Node{ key: k, value: v, left: None, right: None } + } + + /// Performs the top-down splay operation at a current node. The key is the + /// value which is being splayed. The `l` and `r` arguments are storage + /// locations for the traversal down the tree. Once a node is recursed on, + /// one of the children is placed in either 'l' or 'r'. + fn splay(~self, key: &K, + l: &mut Option<~Node>, + r: &mut Option<~Node>) -> ~Node + { + assert!(r.is_none()); + assert!(l.is_none()); + + // When finishing the top-down splay operation, we need to ensure that + // `self` doesn't have any children, so move its remaining children into + // the `l` and `r` arguments. + fn fixup(self: ~Node, l: &mut Option<~Node>, + r: &mut Option<~Node>) -> ~Node { + let mut self = self; + *l = util::replace(&mut self.left, None); + *r = util::replace(&mut self.right, None); + return self; + } + + let mut self = self; + match key.cmp(&self.key) { + // Found it, yay! + Equal => { return fixup(self, l, r); } + + Less => { + match util::replace(&mut self.left, None) { + None => { return fixup(self, l, r); } + Some(left) => { + let mut left = left; + // rotate this node right if necessary + if key.cmp(&left.key) == Less { + self.left = util::replace(&mut left.right, None); + left.right = Some(self); + self = left; + match util::replace(&mut self.left, None) { + Some(l) => { left = l; } + None => { return fixup(self, l, r); } + } + } + + // Bit of an odd way to get some loans, but it works + *r = Some(self); + match *r { + None => fail!(), + Some(ref mut me) => { + return left.splay(key, l, &mut me.left); + } + } + } + } + } + + // If you look closely, you may have seen some similar code before + Greater => { + match util::replace(&mut self.right, None) { + None => { return fixup(self, l, r); } + // rotate left if necessary + Some(right) => { + let mut right = right; + if key.cmp(&right.key) == Greater { + self.right = util::replace(&mut right.left, None); + right.left = Some(self); + self = right; + match util::replace(&mut self.right, None) { + Some(r) => { right = r; } + None => { return fixup(self, l, r); } + } + } + + *l = Some(self); + match *l { + None => fail!(), + Some(ref mut me) => { + return right.splay(key, &mut me.right, r); + } + } + } + } + } + } + } + + fn each<'a>(&'a self, f: &fn(&K, &'a V) -> bool) { + for self.left.each |left| { + left.each(f); + } + f(&self.key, &self.value); + for self.right.each |right| { + right.each(f); + } + } + + fn each_mut(&mut self, f: &fn(&K, &mut V) -> bool) { + match self.left { + None => (), + Some(ref mut left) => left.each_mut(f), + } + f(&self.key, &mut self.value); + match self.right { + None => (), + Some(ref mut right) => right.each_mut(f), + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + // Lots of these are shamelessly stolen from the TreeMap tests, it'd be + // awesome if they could share them... + + #[test] + fn insert_simple() { + let mut t = SplayMap::new(); + assert!(t.insert(1, 2)); + assert!(!t.insert(1, 3)); + assert!(t.insert(2, 3)); + } + + #[test] + fn remove_simple() { + let mut t = SplayMap::new(); + assert!(t.insert(1, 2)); + assert!(t.insert(2, 3)); + assert!(t.insert(3, 4)); + assert!(t.insert(0, 5)); + assert!(t.remove(&1)); + } + + #[test] + fn pop_simple() { + let mut t = SplayMap::new(); + assert!(t.insert(1, 2)); + assert!(t.insert(2, 3)); + assert!(t.insert(3, 4)); + assert!(t.insert(0, 5)); + assert_eq!(t.pop(&1), Some(2)); + assert_eq!(t.pop(&1), None); + assert_eq!(t.pop(&0), Some(5)); + } + + #[test] + fn find_mut_simple() { + let mut t = SplayMap::new(); + assert!(t.insert(1, 2)); + assert!(t.insert(2, 3)); + assert!(t.insert(3, 4)); + assert!(t.insert(0, 5)); + + { + let ptr = t.find_mut(&1); + assert!(ptr.is_some()); + let ptr = ptr.unwrap(); + assert!(*ptr == 2); + *ptr = 4; + } + + let ptr = t.find_mut(&1); + assert!(ptr.is_some()); + assert!(*ptr.unwrap() == 4); + } + + #[test] + fn each_simple() { + let mut m = SplayMap::new(); + assert!(m.insert(3, 6)); + assert!(m.insert(0, 0)); + assert!(m.insert(4, 8)); + assert!(m.insert(2, 4)); + assert!(m.insert(1, 2)); + + let mut n = 0; + for m.each |k, v| { + assert!(*k == n); + assert!(*v == n * 2); + n += 1; + } + } + + #[test] + fn test_len() { + let mut m = SplayMap::new(); + assert!(m.insert(3, 6)); + assert!(m.len() == 1); + assert!(m.insert(0, 0)); + assert!(m.len() == 2); + assert!(m.insert(4, 8)); + assert!(m.len() == 3); + assert!(m.remove(&3)); + assert!(m.len() == 2); + assert!(!m.remove(&5)); + assert!(m.len() == 2); + assert!(m.insert(2, 4)); + assert!(m.len() == 3); + assert!(m.insert(1, 2)); + assert!(m.len() == 4); + } + + #[test] + fn test_clear() { + let mut m = SplayMap::new(); + m.clear(); + assert!(m.insert(5, 11)); + assert!(m.insert(12, -3)); + assert!(m.insert(19, 2)); + m.clear(); + assert!(m.find(&5).is_none()); + assert!(m.find(&12).is_none()); + assert!(m.find(&19).is_none()); + assert!(m.is_empty()); + } + + #[test] + fn insert_replace() { + let mut m = SplayMap::new(); + assert!(m.insert(5, 2)); + assert!(m.insert(2, 9)); + assert!(!m.insert(2, 11)); + assert!(m.find(&2).unwrap() == &11); + } + + #[test] + fn find_empty() { + let m = SplayMap::new::(); + assert!(m.find(&5) == None); + } + + #[test] + fn find_not_found() { + let mut m = SplayMap::new(); + assert!(m.insert(1, 2)); + assert!(m.insert(5, 3)); + assert!(m.insert(9, 3)); + assert!(m.find(&2) == None); + } +} diff --git a/src/libstd/std.rc b/src/libstd/std.rc index 931974d245485..0df772aa32bf2 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -82,6 +82,8 @@ pub mod sort; pub mod dlist; pub mod treemap; +#[cfg(not(stage0))] +pub mod splay; // And ... other stuff diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 06ac1a71bacd0..b5b197184e465 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -198,44 +198,11 @@ pub impl TreeMap { /// Get a lazy iterator over the key-value pairs in the map. /// Requires that it be frozen (immutable). - fn iter<'a>(&'a self) -> TreeMapIterator<'a, K, V> { - TreeMapIterator{stack: ~[], node: &self.root} - } -} - -/// Lazy forward iterator over a map -pub struct TreeMapIterator<'self, K, V> { - priv stack: ~[&'self ~TreeNode], - priv node: &'self Option<~TreeNode> -} - -impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapIterator<'self, K, V> { - /// Advance the iterator to the next node (in order) and return a - /// tuple with a reference to the key and value. If there are no - /// more nodes, return `None`. - fn next(&mut self) -> Option<(&'self K, &'self V)> { - while !self.stack.is_empty() || self.node.is_some() { - match *self.node { - Some(ref x) => { - self.stack.push(x); - self.node = &x.left; - } - None => { - let res = self.stack.pop(); - self.node = &res.right; - return Some((&res.key, &res.value)); - } - } - } - None - } -} - -impl<'self, T> Iterator<&'self T> for TreeSetIterator<'self, T> { - /// Advance the iterator to the next node (in order). If there are no more nodes, return `None`. - #[inline(always)] - fn next(&mut self) -> Option<&'self T> { - do self.iter.next().map |&(value, _)| { value } + fn iter<'a>(&'a self) -> BSTIterator<'a, TreeNode, (&'a K, &'a V)> { + BSTIterator::new(&self.root, + |n| (&n.key, &n.value), + |n| &n.left, + |n| &n.right) } } @@ -313,180 +280,54 @@ impl Set for TreeSet { /// Return true if the set has no elements in common with `other`. /// This is equivalent to checking for an empty intersection. fn is_disjoint(&self, other: &TreeSet) -> bool { - let mut x = self.iter(); - let mut y = other.iter(); - let mut a = x.next(); - let mut b = y.next(); - while a.is_some() && b.is_some() { - let a1 = a.unwrap(); - let b1 = b.unwrap(); - match a1.cmp(b1) { - Less => a = x.next(), - Greater => b = y.next(), - Equal => return false - } + for self.intersection(other) |_| { + return false; } - true + return true; } /// Return true if the set is a subset of another - #[inline(always)] fn is_subset(&self, other: &TreeSet) -> bool { - other.is_superset(self) + let mut amt = 0; + for self.intersection(other) |_| { + amt += 1; + } + return amt == self.len(); } /// Return true if the set is a superset of another + #[inline(always)] fn is_superset(&self, other: &TreeSet) -> bool { - let mut x = self.iter(); - let mut y = other.iter(); - let mut a = x.next(); - let mut b = y.next(); - while b.is_some() { - if a.is_none() { - return false - } - - let a1 = a.unwrap(); - let b1 = b.unwrap(); - - match a1.cmp(b1) { - Less => (), - Greater => return false, - Equal => b = y.next(), - } - - a = x.next(); - } - true + other.is_subset(self) } /// Visit the values (in-order) representing the difference fn difference(&self, other: &TreeSet, f: &fn(&T) -> bool) { - let mut x = self.iter(); - let mut y = other.iter(); - - let mut a = x.next(); - let mut b = y.next(); - - while a.is_some() { - if b.is_none() { - return do a.while_some() |a1| { - if f(a1) { x.next() } else { None } - } - } - - let a1 = a.unwrap(); - let b1 = b.unwrap(); - - let cmp = a1.cmp(b1); - - if cmp == Less { - if !f(a1) { return } - a = x.next(); - } else { - if cmp == Equal { a = x.next() } - b = y.next(); - } - } + let mut me = self.iter(); + let mut i = me.differencei(other.iter()); + i.advance(f) } /// Visit the values (in-order) representing the symmetric difference fn symmetric_difference(&self, other: &TreeSet, - f: &fn(&T) -> bool) { - let mut x = self.iter(); - let mut y = other.iter(); - - let mut a = x.next(); - let mut b = y.next(); - - while a.is_some() { - if b.is_none() { - return do a.while_some() |a1| { - if f(a1) { x.next() } else { None } - } - } - - let a1 = a.unwrap(); - let b1 = b.unwrap(); - - let cmp = a1.cmp(b1); - - if cmp == Less { - if !f(a1) { return } - a = x.next(); - } else { - if cmp == Greater { - if !f(b1) { return } - } else { - a = x.next(); - } - b = y.next(); - } - } - do b.while_some |b1| { - if f(b1) { y.next() } else { None } - } + f: &fn(&T) -> bool) { + let mut me = self.iter(); + let mut i = me.xori(other.iter()); + i.advance(f) } /// Visit the values (in-order) representing the intersection fn intersection(&self, other: &TreeSet, f: &fn(&T) -> bool) { - let mut x = self.iter(); - let mut y = other.iter(); - - let mut a = x.next(); - let mut b = y.next(); - - while a.is_some() && b.is_some() { - let a1 = a.unwrap(); - let b1 = b.unwrap(); - - let cmp = a1.cmp(b1); - - if cmp == Less { - a = x.next(); - } else { - if cmp == Equal { - if !f(a1) { return } - } - b = y.next(); - } - } + let mut me = self.iter(); + let mut i = me.intersecti(other.iter()); + i.advance(f) } /// Visit the values (in-order) representing the union fn union(&self, other: &TreeSet, f: &fn(&T) -> bool) { - let mut x = self.iter(); - let mut y = other.iter(); - - let mut a = x.next(); - let mut b = y.next(); - - while a.is_some() { - if b.is_none() { - return do a.while_some() |a1| { - if f(a1) { x.next() } else { None } - } - } - - let a1 = a.unwrap(); - let b1 = b.unwrap(); - - let cmp = a1.cmp(b1); - - if cmp == Greater { - if !f(b1) { return } - b = y.next(); - } else { - if !f(a1) { return } - if cmp == Equal { - b = y.next(); - } - a = x.next(); - } - } - do b.while_some |b1| { - if f(b1) { y.next() } else { None } - } + let mut me = self.iter(); + let mut i = me.unioni(other.iter()); + i.advance(f) } } @@ -498,16 +339,14 @@ pub impl TreeSet { /// Get a lazy iterator over the values in the set. /// Requires that it be frozen (immutable). #[inline(always)] - fn iter<'a>(&'a self) -> TreeSetIterator<'a, T> { - TreeSetIterator{iter: self.map.iter()} + fn iter<'a>(&'a self) -> + MapIterator<(&'a T, &'a ()), &'a T, + BSTIterator<'a, TreeNode, (&'a T, &'a ())>> // ouch + { + self.map.iter().transform(|(a, _)| a) } } -/// Lazy forward iterator over a set -pub struct TreeSetIterator<'self, T> { - priv iter: TreeMapIterator<'self, T, ()> -} - // Nodes keep track of their level in the tree, starting at 1 in the // leaves and with a red child sharing the level of the parent. struct TreeNode { diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs index cb494ec9d206a..33caff90295b7 100644 --- a/src/test/bench/core-map.rs +++ b/src/test/bench/core-map.rs @@ -13,6 +13,7 @@ extern mod std; use core::io; use std::time; use std::treemap::TreeMap; +use std::splay::SplayMap; use core::hashmap::{HashMap, HashSet}; use core::trie::TrieMap; use core::rand::Rng; @@ -168,4 +169,22 @@ fn main() { let mut map = TrieMap::new::(); vector(&mut map, n_keys, rand); } + + io::println("\nSplayMap:"); + + { + let mut map = SplayMap::new::(); + ascending(&mut map, n_keys); + } + + { + let mut map = SplayMap::new::(); + descending(&mut map, n_keys); + } + + { + io::println(" Random integers:"); + let mut map = SplayMap::new::(); + vector(&mut map, n_keys, rand); + } } diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs index bae21c6d4a325..21666f2643a88 100644 --- a/src/test/bench/core-set.rs +++ b/src/test/bench/core-set.rs @@ -12,6 +12,7 @@ extern mod std; use core::hashmap::HashSet; use std::bitv::BitvSet; use std::treemap::TreeSet; +use std::splay::SplaySet; struct Results { sequential_ints: float, @@ -179,6 +180,14 @@ fn main() { write_results("std::treemap::TreeSet", &results); } + { + let mut rng = rand::IsaacRng::new_seeded(seed); + let mut results = empty_results(); + results.bench_int(&mut rng, num_keys, max, || SplaySet::new::()); + results.bench_str(&mut rng, num_keys, || SplaySet::new::<~str>()); + write_results("std::treemap::SplaySet", &results); + } + { let mut rng = rand::IsaacRng::new_seeded(seed); let mut results = empty_results();