2013-01-14 09:27:26 -06:00
|
|
|
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
2012-12-03 18:48:01 -06:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2013-01-14 09:27:26 -06:00
|
|
|
//! An ordered map and set implemented as self-balancing binary search
|
|
|
|
//! trees. The only requirement for the types is that the key implements
|
2014-05-31 12:43:52 -05:00
|
|
|
//! `Ord`.
|
2014-07-16 17:11:40 -05:00
|
|
|
//!
|
|
|
|
//! ## Example
|
|
|
|
//!
|
|
|
|
//! ```{rust}
|
|
|
|
//! use std::collections::TreeSet;
|
|
|
|
//!
|
|
|
|
//! let mut tree_set = TreeSet::new();
|
|
|
|
//!
|
|
|
|
//! tree_set.insert(2i);
|
|
|
|
//! tree_set.insert(1i);
|
|
|
|
//! tree_set.insert(3i);
|
|
|
|
//!
|
|
|
|
//! for i in tree_set.iter() {
|
|
|
|
//! println!("{}", i) // prints 1, then 2, then 3
|
|
|
|
//! }
|
|
|
|
//! ```
|
2013-01-14 09:27:26 -06:00
|
|
|
|
std: Recreate a `collections` module
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:
* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
of libcollections is reexported through this module.
I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.
There are a number of notable points about the new organization:
* std::{str, slice, string, vec} all moved to libcollections. There is no reason
that these primitives shouldn't be necessarily usable in a freestanding
context that has allocation. These are all reexported in their usual places in
the standard library.
* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
`libcollections`, but rather in libstd. The reason for this is because the
`HashMap::new` contructor requires access to the OSRng for initially seeding
the hash map. Beyond this requirement, there is no reason that the hashmap
could not move to libcollections.
I do, however, have a plan to move the hash map to the collections module. The
`HashMap::new` function could be altered to require that the `H` hasher
parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
to live in libcollections. The key idea would be that the default hasher would
be different in libstd. Something along the lines of:
// src/libstd/collections/mod.rs
pub type HashMap<K, V, H = RandomizedSipHasher> =
core_collections::HashMap<K, V, H>;
This is not possible today because you cannot invoke static methods through
type aliases. If we modified the compiler, however, to allow invocation of
static methods through type aliases, then this type definition would
essentially be switching the default hasher from `SipHasher` in libcollections
to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
implementation would randomly seed the `SipHasher` instance, and otherwise
perform the same as `SipHasher`.
This future state doesn't seem incredibly far off, but until that time comes,
the hashmap module will live in libstd to not compromise on functionality.
* In preparation for the hashmap moving to libcollections, the `hash` module has
moved from libstd to libcollections. A previously snapshotted commit enables a
distinct `Writer` trait to live in the `hash` module which `Hash`
implementations are now parameterized over.
Due to using a custom trait, the `SipHasher` implementation has lost its
specialized methods for writing integers. These can be re-added
backwards-compatibly in the future via default methods if necessary, but the
FNV hashing should satisfy much of the need for speedier hashing.
A list of breaking changes:
* HashMap::{get, get_mut} no longer fails with the key formatted into the error
message with `{:?}`, instead, a generic message is printed. With backtraces,
it should still be not-too-hard to track down errors.
* The HashMap, HashSet, and LruCache types are now available through
std::collections instead of the collections crate.
* Manual implementations of hash should be parameterized over `hash::Writer`
instead of just `Writer`.
[breaking-change]
2014-05-29 20:50:12 -05:00
|
|
|
use core::prelude::*;
|
|
|
|
|
2014-07-10 16:19:17 -05:00
|
|
|
use alloc::boxed::Box;
|
2014-06-09 02:30:04 -05:00
|
|
|
use core::default::Default;
|
std: Recreate a `collections` module
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:
* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
of libcollections is reexported through this module.
I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.
There are a number of notable points about the new organization:
* std::{str, slice, string, vec} all moved to libcollections. There is no reason
that these primitives shouldn't be necessarily usable in a freestanding
context that has allocation. These are all reexported in their usual places in
the standard library.
* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
`libcollections`, but rather in libstd. The reason for this is because the
`HashMap::new` contructor requires access to the OSRng for initially seeding
the hash map. Beyond this requirement, there is no reason that the hashmap
could not move to libcollections.
I do, however, have a plan to move the hash map to the collections module. The
`HashMap::new` function could be altered to require that the `H` hasher
parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
to live in libcollections. The key idea would be that the default hasher would
be different in libstd. Something along the lines of:
// src/libstd/collections/mod.rs
pub type HashMap<K, V, H = RandomizedSipHasher> =
core_collections::HashMap<K, V, H>;
This is not possible today because you cannot invoke static methods through
type aliases. If we modified the compiler, however, to allow invocation of
static methods through type aliases, then this type definition would
essentially be switching the default hasher from `SipHasher` in libcollections
to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
implementation would randomly seed the `SipHasher` instance, and otherwise
perform the same as `SipHasher`.
This future state doesn't seem incredibly far off, but until that time comes,
the hashmap module will live in libstd to not compromise on functionality.
* In preparation for the hashmap moving to libcollections, the `hash` module has
moved from libstd to libcollections. A previously snapshotted commit enables a
distinct `Writer` trait to live in the `hash` module which `Hash`
implementations are now parameterized over.
Due to using a custom trait, the `SipHasher` implementation has lost its
specialized methods for writing integers. These can be re-added
backwards-compatibly in the future via default methods if necessary, but the
FNV hashing should satisfy much of the need for speedier hashing.
A list of breaking changes:
* HashMap::{get, get_mut} no longer fails with the key formatted into the error
message with `{:?}`, instead, a generic message is printed. With backtraces,
it should still be not-too-hard to track down errors.
* The HashMap, HashSet, and LruCache types are now available through
std::collections instead of the collections crate.
* Manual implementations of hash should be parameterized over `hash::Writer`
instead of just `Writer`.
[breaking-change]
2014-05-29 20:50:12 -05:00
|
|
|
use core::fmt;
|
|
|
|
use core::fmt::Show;
|
|
|
|
use core::iter::Peekable;
|
|
|
|
use core::iter;
|
|
|
|
use core::mem::{replace, swap};
|
|
|
|
use core::ptr;
|
2014-07-12 12:23:20 -05:00
|
|
|
use std::hash::{Writer, Hash};
|
std: Recreate a `collections` module
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:
* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
of libcollections is reexported through this module.
I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.
There are a number of notable points about the new organization:
* std::{str, slice, string, vec} all moved to libcollections. There is no reason
that these primitives shouldn't be necessarily usable in a freestanding
context that has allocation. These are all reexported in their usual places in
the standard library.
* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
`libcollections`, but rather in libstd. The reason for this is because the
`HashMap::new` contructor requires access to the OSRng for initially seeding
the hash map. Beyond this requirement, there is no reason that the hashmap
could not move to libcollections.
I do, however, have a plan to move the hash map to the collections module. The
`HashMap::new` function could be altered to require that the `H` hasher
parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
to live in libcollections. The key idea would be that the default hasher would
be different in libstd. Something along the lines of:
// src/libstd/collections/mod.rs
pub type HashMap<K, V, H = RandomizedSipHasher> =
core_collections::HashMap<K, V, H>;
This is not possible today because you cannot invoke static methods through
type aliases. If we modified the compiler, however, to allow invocation of
static methods through type aliases, then this type definition would
essentially be switching the default hasher from `SipHasher` in libcollections
to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
implementation would randomly seed the `SipHasher` instance, and otherwise
perform the same as `SipHasher`.
This future state doesn't seem incredibly far off, but until that time comes,
the hashmap module will live in libstd to not compromise on functionality.
* In preparation for the hashmap moving to libcollections, the `hash` module has
moved from libstd to libcollections. A previously snapshotted commit enables a
distinct `Writer` trait to live in the `hash` module which `Hash`
implementations are now parameterized over.
Due to using a custom trait, the `SipHasher` implementation has lost its
specialized methods for writing integers. These can be re-added
backwards-compatibly in the future via default methods if necessary, but the
FNV hashing should satisfy much of the need for speedier hashing.
A list of breaking changes:
* HashMap::{get, get_mut} no longer fails with the key formatted into the error
message with `{:?}`, instead, a generic message is printed. With backtraces,
it should still be not-too-hard to track down errors.
* The HashMap, HashSet, and LruCache types are now available through
std::collections instead of the collections crate.
* Manual implementations of hash should be parameterized over `hash::Writer`
instead of just `Writer`.
[breaking-change]
2014-05-29 20:50:12 -05:00
|
|
|
|
2014-06-06 18:33:44 -05:00
|
|
|
use {Collection, Mutable, Set, MutableSet, MutableMap, Map};
|
std: Recreate a `collections` module
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:
* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
of libcollections is reexported through this module.
I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.
There are a number of notable points about the new organization:
* std::{str, slice, string, vec} all moved to libcollections. There is no reason
that these primitives shouldn't be necessarily usable in a freestanding
context that has allocation. These are all reexported in their usual places in
the standard library.
* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
`libcollections`, but rather in libstd. The reason for this is because the
`HashMap::new` contructor requires access to the OSRng for initially seeding
the hash map. Beyond this requirement, there is no reason that the hashmap
could not move to libcollections.
I do, however, have a plan to move the hash map to the collections module. The
`HashMap::new` function could be altered to require that the `H` hasher
parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
to live in libcollections. The key idea would be that the default hasher would
be different in libstd. Something along the lines of:
// src/libstd/collections/mod.rs
pub type HashMap<K, V, H = RandomizedSipHasher> =
core_collections::HashMap<K, V, H>;
This is not possible today because you cannot invoke static methods through
type aliases. If we modified the compiler, however, to allow invocation of
static methods through type aliases, then this type definition would
essentially be switching the default hasher from `SipHasher` in libcollections
to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
implementation would randomly seed the `SipHasher` instance, and otherwise
perform the same as `SipHasher`.
This future state doesn't seem incredibly far off, but until that time comes,
the hashmap module will live in libstd to not compromise on functionality.
* In preparation for the hashmap moving to libcollections, the `hash` module has
moved from libstd to libcollections. A previously snapshotted commit enables a
distinct `Writer` trait to live in the `hash` module which `Hash`
implementations are now parameterized over.
Due to using a custom trait, the `SipHasher` implementation has lost its
specialized methods for writing integers. These can be re-added
backwards-compatibly in the future via default methods if necessary, but the
FNV hashing should satisfy much of the need for speedier hashing.
A list of breaking changes:
* HashMap::{get, get_mut} no longer fails with the key formatted into the error
message with `{:?}`, instead, a generic message is printed. With backtraces,
it should still be not-too-hard to track down errors.
* The HashMap, HashSet, and LruCache types are now available through
std::collections instead of the collections crate.
* Manual implementations of hash should be parameterized over `hash::Writer`
instead of just `Writer`.
[breaking-change]
2014-05-29 20:50:12 -05:00
|
|
|
use vec::Vec;
|
2011-08-25 19:19:23 -05:00
|
|
|
|
2013-01-14 09:27:26 -06:00
|
|
|
// This is implemented as an AA tree, which is a simplified variation of
|
2013-06-06 02:38:41 -05:00
|
|
|
// a red-black tree where red (horizontal) nodes can only be added
|
2013-01-14 09:27:26 -06:00
|
|
|
// as a right child. The time complexity is the same, and re-balancing
|
|
|
|
// operations are more frequent but also cheaper.
|
2012-05-23 19:18:31 -05:00
|
|
|
|
2013-01-15 05:45:30 -06:00
|
|
|
// Future improvements:
|
|
|
|
|
2013-01-15 08:50:51 -06:00
|
|
|
// range search - O(log n) retrieval of an iterator from some key
|
|
|
|
|
2013-01-15 05:45:30 -06:00
|
|
|
// (possibly) implement the overloads Python does for sets:
|
2013-01-14 09:27:26 -06:00
|
|
|
// * intersection: &
|
|
|
|
// * difference: -
|
|
|
|
// * symmetric difference: ^
|
2013-01-29 18:30:26 -06:00
|
|
|
// * union: |
|
2013-01-15 11:44:43 -06:00
|
|
|
// These would be convenient since the methods work like `each`
|
2013-01-14 09:27:26 -06:00
|
|
|
|
2013-05-28 22:11:41 -05:00
|
|
|
#[allow(missing_doc)]
|
2013-07-17 17:15:34 -05:00
|
|
|
#[deriving(Clone)]
|
2013-01-28 12:46:43 -06:00
|
|
|
pub struct TreeMap<K, V> {
|
2014-05-05 20:56:44 -05:00
|
|
|
root: Option<Box<TreeNode<K, V>>>,
|
2014-03-27 17:10:04 -05:00
|
|
|
length: uint
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<K: PartialEq + Ord, V: PartialEq> PartialEq for TreeMap<K, V> {
|
2013-03-21 23:34:30 -05:00
|
|
|
fn eq(&self, other: &TreeMap<K, V>) -> bool {
|
2013-08-06 10:27:39 -05:00
|
|
|
self.len() == other.len() &&
|
|
|
|
self.iter().zip(other.iter()).all(|(a, b)| a == b)
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
2011-08-25 19:19:23 -05:00
|
|
|
}
|
|
|
|
|
2014-06-18 01:25:51 -05:00
|
|
|
impl<K: Ord, V: PartialOrd> PartialOrd for TreeMap<K, V> {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2014-06-18 01:25:51 -05:00
|
|
|
fn partial_cmp(&self, other: &TreeMap<K, V>) -> Option<Ordering> {
|
|
|
|
iter::order::partial_cmp(self.iter(), other.iter())
|
|
|
|
}
|
2013-01-26 11:40:41 -06:00
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<K: Ord + Show, V: Show> Show for TreeMap<K, V> {
|
2014-05-28 11:24:28 -05:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
try!(write!(f, "{{"));
|
|
|
|
|
|
|
|
for (i, (k, v)) in self.iter().enumerate() {
|
|
|
|
if i != 0 { try!(write!(f, ", ")); }
|
|
|
|
try!(write!(f, "{}: {}", *k, *v));
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, "}}")
|
|
|
|
}
|
2014-05-27 12:38:52 -05:00
|
|
|
}
|
|
|
|
|
2014-05-19 13:32:09 -05:00
|
|
|
impl<K: Ord, V> Collection for TreeMap<K, V> {
|
2013-06-23 22:44:11 -05:00
|
|
|
fn len(&self) -> uint { self.length }
|
2013-01-21 20:59:19 -06:00
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<K: Ord, V> Mutable for TreeMap<K, V> {
|
2013-01-21 16:25:57 -06:00
|
|
|
fn clear(&mut self) {
|
|
|
|
self.root = None;
|
|
|
|
self.length = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<K: Ord, V> Map<K, V> for TreeMap<K, V> {
|
2014-07-09 09:48:17 -05:00
|
|
|
// See comments on tree_find_with
|
|
|
|
#[inline]
|
2013-04-10 15:14:06 -05:00
|
|
|
fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
|
2014-07-09 09:48:17 -05:00
|
|
|
tree_find_with(&self.root, |k2| key.cmp(k2))
|
2013-04-10 15:14:06 -05:00
|
|
|
}
|
2013-07-13 21:44:36 -05:00
|
|
|
}
|
2013-04-10 15:14:06 -05:00
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<K: Ord, V> MutableMap<K, V> for TreeMap<K, V> {
|
2014-07-09 09:48:17 -05:00
|
|
|
// See comments on def_tree_find_mut_with
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-04-10 15:14:06 -05:00
|
|
|
fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
|
2014-07-09 09:48:17 -05:00
|
|
|
tree_find_mut_with(&mut self.root, |x| key.cmp(x))
|
2013-04-10 15:14:06 -05:00
|
|
|
}
|
|
|
|
|
2013-05-04 08:54:58 -05:00
|
|
|
fn swap(&mut self, key: K, value: V) -> Option<V> {
|
|
|
|
let ret = insert(&mut self.root, key, value);
|
|
|
|
if ret.is_none() { self.length += 1 }
|
|
|
|
ret
|
|
|
|
}
|
|
|
|
|
|
|
|
fn pop(&mut self, key: &K) -> Option<V> {
|
2013-01-21 17:22:03 -06:00
|
|
|
let ret = remove(&mut self.root, key);
|
2013-05-04 08:54:58 -05:00
|
|
|
if ret.is_some() { self.length -= 1 }
|
2013-01-21 17:22:03 -06:00
|
|
|
ret
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-09 02:30:04 -05:00
|
|
|
impl<K: Ord, V> Default for TreeMap<K,V> {
|
|
|
|
#[inline]
|
|
|
|
fn default() -> TreeMap<K, V> { TreeMap::new() }
|
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<K: Ord, V> TreeMap<K, V> {
|
2013-05-02 17:33:27 -05:00
|
|
|
/// Create an empty TreeMap
|
2013-05-31 17:17:22 -05:00
|
|
|
pub fn new() -> TreeMap<K, V> { TreeMap{root: None, length: 0} }
|
2013-05-02 17:33:27 -05:00
|
|
|
|
|
|
|
/// Get a lazy iterator over the key-value pairs in the map.
|
|
|
|
/// Requires that it be frozen (immutable).
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn iter<'a>(&'a self) -> Entries<'a, K, V> {
|
|
|
|
Entries {
|
2014-04-05 00:45:42 -05:00
|
|
|
stack: vec!(),
|
2013-10-30 18:44:55 -05:00
|
|
|
node: deref(&self.root),
|
2013-08-01 15:59:07 -05:00
|
|
|
remaining_min: self.length,
|
|
|
|
remaining_max: self.length
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-06 14:57:46 -05:00
|
|
|
/// Get a lazy reverse iterator over the key-value pairs in the map.
|
|
|
|
/// Requires that it be frozen (immutable).
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn rev_iter<'a>(&'a self) -> RevEntries<'a, K, V> {
|
|
|
|
RevEntries{iter: self.iter()}
|
2013-08-06 14:57:46 -05:00
|
|
|
}
|
|
|
|
|
2014-01-05 07:40:53 -06:00
|
|
|
/// Get a lazy forward iterator over the key-value pairs in the
|
|
|
|
/// map, with the values being mutable.
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, K, V> {
|
|
|
|
MutEntries {
|
2014-04-05 00:45:42 -05:00
|
|
|
stack: vec!(),
|
2014-01-05 07:40:53 -06:00
|
|
|
node: mut_deref(&mut self.root),
|
|
|
|
remaining_min: self.length,
|
|
|
|
remaining_max: self.length
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// Get a lazy reverse iterator over the key-value pairs in the
|
|
|
|
/// map, with the values being mutable.
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn mut_rev_iter<'a>(&'a mut self) -> RevMutEntries<'a, K, V> {
|
|
|
|
RevMutEntries{iter: self.mut_iter()}
|
2014-01-05 07:40:53 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-01-05 08:53:27 -06:00
|
|
|
/// Get a lazy iterator that consumes the treemap.
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn move_iter(self) -> MoveEntries<K, V> {
|
2014-01-05 08:53:27 -06:00
|
|
|
let TreeMap { root: root, length: length } = self;
|
|
|
|
let stk = match root {
|
2014-04-05 00:45:42 -05:00
|
|
|
None => vec!(),
|
2014-05-05 20:56:44 -05:00
|
|
|
Some(box tn) => vec!(tn)
|
2014-01-05 08:53:27 -06:00
|
|
|
};
|
2014-01-14 21:32:24 -06:00
|
|
|
MoveEntries {
|
2014-01-05 08:53:27 -06:00
|
|
|
stack: stk,
|
|
|
|
remaining: length
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-09 09:48:17 -05:00
|
|
|
impl<K, V> TreeMap<K, V> {
|
|
|
|
/// Return the value for which f(key) returns Equal. f is invoked
|
|
|
|
/// with current key and helps to navigate the tree
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::ascii::StrAsciiExt;
|
|
|
|
///
|
|
|
|
/// let mut t = collections::treemap::TreeMap::new();
|
|
|
|
/// t.insert("Content-Type", "application/xml");
|
|
|
|
/// t.insert("User-Agent", "Curl-Rust/0.1");
|
|
|
|
///
|
|
|
|
/// let ua_key = "user-agent";
|
|
|
|
/// let ua = t.find_with(|&k| {
|
|
|
|
/// ua_key.cmp(&k.to_ascii_lower().as_slice())
|
|
|
|
/// });
|
|
|
|
///
|
|
|
|
/// assert_eq!(*ua.unwrap(), "Curl-Rust/0.1");
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn find_with<'a>(&'a self, f:|&K| -> Ordering) -> Option<&'a V> {
|
|
|
|
tree_find_with(&self.root, f)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Return the value for which f(key) returns Equal. f is invoked
|
|
|
|
/// with current key and helps to navigate the tree
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// let mut t = collections::treemap::TreeMap::new();
|
|
|
|
/// t.insert("Content-Type", "application/xml");
|
|
|
|
/// t.insert("User-Agent", "Curl-Rust/0.1");
|
|
|
|
///
|
|
|
|
/// let new_ua = "Safari/156.0";
|
|
|
|
/// match t.find_mut_with(|k| "User-Agent".cmp(k)) {
|
|
|
|
/// Some(x) => *x = new_ua,
|
|
|
|
/// None => fail!(),
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// assert_eq!(t.find(&"User-Agent"), Some(&new_ua));
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn find_mut_with<'a>(&'a mut self, f:|&K| -> Ordering) -> Option<&'a mut V> {
|
|
|
|
tree_find_mut_with(&mut self.root, f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-05 08:53:27 -06:00
|
|
|
// range iterators.
|
|
|
|
|
|
|
|
macro_rules! bound_setup {
|
|
|
|
// initialiser of the iterator to manipulate
|
2014-07-07 18:26:30 -05:00
|
|
|
($iter:expr, $k:expr,
|
2014-01-05 08:53:27 -06:00
|
|
|
// whether we are looking for the lower or upper bound.
|
|
|
|
$is_lower_bound:expr) => {
|
|
|
|
{
|
|
|
|
let mut iter = $iter;
|
|
|
|
loop {
|
|
|
|
if !iter.node.is_null() {
|
|
|
|
let node_k = unsafe {&(*iter.node).key};
|
2014-07-07 18:26:30 -05:00
|
|
|
match $k.cmp(node_k) {
|
2014-01-05 08:53:27 -06:00
|
|
|
Less => iter.traverse_left(),
|
|
|
|
Greater => iter.traverse_right(),
|
|
|
|
Equal => {
|
|
|
|
if $is_lower_bound {
|
|
|
|
iter.traverse_complete();
|
|
|
|
return iter;
|
|
|
|
} else {
|
|
|
|
iter.traverse_right()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
iter.traverse_complete();
|
|
|
|
return iter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<K: Ord, V> TreeMap<K, V> {
|
2013-08-01 15:59:07 -05:00
|
|
|
/// Get a lazy iterator that should be initialized using
|
2014-01-05 08:53:27 -06:00
|
|
|
/// `traverse_left`/`traverse_right`/`traverse_complete`.
|
2014-01-14 21:32:24 -06:00
|
|
|
fn iter_for_traversal<'a>(&'a self) -> Entries<'a, K, V> {
|
|
|
|
Entries {
|
2014-04-05 00:45:42 -05:00
|
|
|
stack: vec!(),
|
2013-10-30 18:44:55 -05:00
|
|
|
node: deref(&self.root),
|
2013-08-01 15:59:07 -05:00
|
|
|
remaining_min: 0,
|
|
|
|
remaining_max: self.length
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Return a lazy iterator to the first key-value pair whose key is not less than `k`
|
|
|
|
/// If all keys in map are less than `k` an empty iterator is returned.
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn lower_bound<'a>(&'a self, k: &K) -> Entries<'a, K, V> {
|
2014-07-07 18:26:30 -05:00
|
|
|
bound_setup!(self.iter_for_traversal(), k, true)
|
2013-08-01 15:59:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Return a lazy iterator to the first key-value pair whose key is greater than `k`
|
|
|
|
/// If all keys in map are not greater than `k` an empty iterator is returned.
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn upper_bound<'a>(&'a self, k: &K) -> Entries<'a, K, V> {
|
2014-07-07 18:26:30 -05:00
|
|
|
bound_setup!(self.iter_for_traversal(), k, false)
|
2013-05-02 17:33:27 -05:00
|
|
|
}
|
2014-01-05 08:53:27 -06:00
|
|
|
|
2014-01-05 07:40:53 -06:00
|
|
|
/// Get a lazy iterator that should be initialized using
|
2014-01-05 08:53:27 -06:00
|
|
|
/// `traverse_left`/`traverse_right`/`traverse_complete`.
|
2014-01-14 21:32:24 -06:00
|
|
|
fn mut_iter_for_traversal<'a>(&'a mut self) -> MutEntries<'a, K, V> {
|
|
|
|
MutEntries {
|
2014-04-05 00:45:42 -05:00
|
|
|
stack: vec!(),
|
2014-01-05 07:40:53 -06:00
|
|
|
node: mut_deref(&mut self.root),
|
|
|
|
remaining_min: 0,
|
|
|
|
remaining_max: self.length
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Return a lazy value iterator to the first key-value pair (with
|
|
|
|
/// the value being mutable) whose key is not less than `k`.
|
|
|
|
///
|
|
|
|
/// If all keys in map are less than `k` an empty iterator is
|
|
|
|
/// returned.
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn mut_lower_bound<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> {
|
2014-07-07 18:26:30 -05:00
|
|
|
bound_setup!(self.mut_iter_for_traversal(), k, true)
|
2014-01-05 07:40:53 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Return a lazy iterator to the first key-value pair (with the
|
|
|
|
/// value being mutable) whose key is greater than `k`.
|
|
|
|
///
|
|
|
|
/// If all keys in map are not greater than `k` an empty iterator
|
|
|
|
/// is returned.
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn mut_upper_bound<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> {
|
2014-07-07 18:26:30 -05:00
|
|
|
bound_setup!(self.mut_iter_for_traversal(), k, false)
|
2013-07-18 14:37:18 -05:00
|
|
|
}
|
2013-05-02 17:33:27 -05:00
|
|
|
}
|
2013-01-14 19:41:11 -06:00
|
|
|
|
|
|
|
/// Lazy forward iterator over a map
|
2014-01-14 21:32:24 -06:00
|
|
|
pub struct Entries<'a, K, V> {
|
2014-04-05 00:45:42 -05:00
|
|
|
stack: Vec<&'a TreeNode<K, V>>,
|
2014-01-14 21:32:24 -06:00
|
|
|
// See the comment on MutEntries; this is just to allow
|
2014-01-05 08:53:27 -06:00
|
|
|
// code-sharing (for this immutable-values iterator it *could* very
|
|
|
|
// well be Option<&'a TreeNode<K,V>>).
|
2014-06-25 14:47:34 -05:00
|
|
|
node: *const TreeNode<K, V>,
|
2014-03-27 17:10:04 -05:00
|
|
|
remaining_min: uint,
|
|
|
|
remaining_max: uint
|
2011-08-25 19:19:23 -05:00
|
|
|
}
|
2011-08-26 12:50:02 -05:00
|
|
|
|
2013-08-06 14:57:46 -05:00
|
|
|
/// Lazy backward iterator over a map
|
2014-01-14 21:32:24 -06:00
|
|
|
pub struct RevEntries<'a, K, V> {
|
2014-03-27 17:10:04 -05:00
|
|
|
iter: Entries<'a, K, V>,
|
2013-08-06 14:57:46 -05:00
|
|
|
}
|
|
|
|
|
2014-01-05 07:40:53 -06:00
|
|
|
/// Lazy forward iterator over a map that allows for the mutation of
|
|
|
|
/// the values.
|
2014-01-14 21:32:24 -06:00
|
|
|
pub struct MutEntries<'a, K, V> {
|
2014-04-05 00:45:42 -05:00
|
|
|
stack: Vec<&'a mut TreeNode<K, V>>,
|
2014-01-05 07:40:53 -06:00
|
|
|
// Unfortunately, we require some unsafe-ness to get around the
|
|
|
|
// fact that we would be storing a reference *into* one of the
|
|
|
|
// nodes in the stack.
|
|
|
|
//
|
|
|
|
// As far as the compiler knows, this would let us invalidate the
|
|
|
|
// reference by assigning a new value to this node's position in
|
|
|
|
// its parent, which would cause this current one to be
|
|
|
|
// deallocated so this reference would be invalid. (i.e. the
|
|
|
|
// compilers complaints are 100% correct.)
|
|
|
|
//
|
|
|
|
// However, as far as you humans reading this code know (or are
|
|
|
|
// about to know, if you haven't read far enough down yet), we are
|
|
|
|
// only reading from the TreeNode.{left,right} fields. the only
|
|
|
|
// thing that is ever mutated is the .value field (although any
|
|
|
|
// actual mutation that happens is done externally, by the
|
|
|
|
// iterator consumer). So, don't be so concerned, rustc, we've got
|
|
|
|
// it under control.
|
|
|
|
//
|
|
|
|
// (This field can legitimately be null.)
|
2014-03-27 17:10:04 -05:00
|
|
|
node: *mut TreeNode<K, V>,
|
|
|
|
remaining_min: uint,
|
|
|
|
remaining_max: uint
|
2014-01-05 07:40:53 -06:00
|
|
|
}
|
|
|
|
|
2014-01-05 08:53:27 -06:00
|
|
|
/// Lazy backward iterator over a map
|
2014-01-14 21:32:24 -06:00
|
|
|
pub struct RevMutEntries<'a, K, V> {
|
2014-03-27 17:10:04 -05:00
|
|
|
iter: MutEntries<'a, K, V>,
|
2014-01-05 08:53:27 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// FIXME #5846 we want to be able to choose between &x and &mut x
|
|
|
|
// (with many different `x`) below, so we need to optionally pass mut
|
|
|
|
// as a tt, but the only thing we can do with a `tt` is pass them to
|
|
|
|
// other macros, so this takes the `& <mutability> <operand>` token
|
2014-04-20 23:49:39 -05:00
|
|
|
// sequence and forces their evaluation as an expression.
|
2014-01-05 08:53:27 -06:00
|
|
|
macro_rules! addr { ($e:expr) => { $e }}
|
2014-01-06 09:09:07 -06:00
|
|
|
// putting an optional mut into type signatures
|
|
|
|
macro_rules! item { ($i:item) => { $i }}
|
2014-01-05 08:53:27 -06:00
|
|
|
|
|
|
|
macro_rules! define_iterator {
|
|
|
|
($name:ident,
|
|
|
|
$rev_name:ident,
|
|
|
|
|
2014-05-05 20:56:44 -05:00
|
|
|
// the function to go from &m Option<Box<TreeNode>> to *m TreeNode
|
2014-01-05 08:53:27 -06:00
|
|
|
deref = $deref:ident,
|
|
|
|
|
|
|
|
// see comment on `addr!`, this is just an optional `mut`, but
|
|
|
|
// there's no support for 0-or-1 repeats.
|
|
|
|
addr_mut = $($addr_mut:tt)*
|
|
|
|
) => {
|
2014-01-06 09:09:07 -06:00
|
|
|
// private methods on the forward iterator (item!() for the
|
|
|
|
// addr_mut in the next_ return value)
|
|
|
|
item!(impl<'a, K, V> $name<'a, K, V> {
|
2014-01-05 08:53:27 -06:00
|
|
|
#[inline(always)]
|
2014-01-06 09:09:07 -06:00
|
|
|
fn next_(&mut self, forward: bool) -> Option<(&'a K, &'a $($addr_mut)* V)> {
|
2014-01-05 08:53:27 -06:00
|
|
|
while !self.stack.is_empty() || !self.node.is_null() {
|
|
|
|
if !self.node.is_null() {
|
|
|
|
let node = unsafe {addr!(& $($addr_mut)* *self.node)};
|
|
|
|
{
|
|
|
|
let next_node = if forward {
|
|
|
|
addr!(& $($addr_mut)* node.left)
|
|
|
|
} else {
|
|
|
|
addr!(& $($addr_mut)* node.right)
|
|
|
|
};
|
|
|
|
self.node = $deref(next_node);
|
|
|
|
}
|
|
|
|
self.stack.push(node);
|
|
|
|
} else {
|
2013-12-23 09:20:52 -06:00
|
|
|
let node = self.stack.pop().unwrap();
|
2014-01-05 08:53:27 -06:00
|
|
|
let next_node = if forward {
|
|
|
|
addr!(& $($addr_mut)* node.right)
|
|
|
|
} else {
|
|
|
|
addr!(& $($addr_mut)* node.left)
|
|
|
|
};
|
|
|
|
self.node = $deref(next_node);
|
|
|
|
self.remaining_max -= 1;
|
|
|
|
if self.remaining_min > 0 {
|
|
|
|
self.remaining_min -= 1;
|
|
|
|
}
|
|
|
|
return Some((&node.key, addr!(& $($addr_mut)* node.value)));
|
|
|
|
}
|
2014-01-05 07:40:53 -06:00
|
|
|
}
|
2014-01-05 08:53:27 -06:00
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
/// traverse_left, traverse_right and traverse_complete are
|
2014-01-14 21:32:24 -06:00
|
|
|
/// used to initialize Entries/MutEntries
|
2014-01-05 08:53:27 -06:00
|
|
|
/// pointing to element inside tree structure.
|
|
|
|
///
|
|
|
|
/// They should be used in following manner:
|
|
|
|
/// - create iterator using TreeMap::[mut_]iter_for_traversal
|
|
|
|
/// - find required node using `traverse_left`/`traverse_right`
|
2014-01-14 21:32:24 -06:00
|
|
|
/// (current node is `Entries::node` field)
|
2014-01-05 08:53:27 -06:00
|
|
|
/// - complete initialization with `traverse_complete`
|
|
|
|
///
|
|
|
|
/// After this, iteration will start from `self.node`. If
|
|
|
|
/// `self.node` is None iteration will start from last
|
|
|
|
/// node from which we traversed left.
|
|
|
|
#[inline]
|
|
|
|
fn traverse_left(&mut self) {
|
|
|
|
let node = unsafe {addr!(& $($addr_mut)* *self.node)};
|
|
|
|
self.node = $deref(addr!(& $($addr_mut)* node.left));
|
2014-01-05 07:40:53 -06:00
|
|
|
self.stack.push(node);
|
2014-01-05 08:53:27 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn traverse_right(&mut self) {
|
|
|
|
let node = unsafe {addr!(& $($addr_mut)* *self.node)};
|
|
|
|
self.node = $deref(addr!(& $($addr_mut)* node.right));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn traverse_complete(&mut self) {
|
|
|
|
if !self.node.is_null() {
|
|
|
|
unsafe {
|
|
|
|
self.stack.push(addr!(& $($addr_mut)* *self.node));
|
|
|
|
}
|
|
|
|
self.node = ptr::RawPtr::null();
|
2014-01-05 07:40:53 -06:00
|
|
|
}
|
|
|
|
}
|
2014-01-06 09:09:07 -06:00
|
|
|
})
|
2014-01-05 07:40:53 -06:00
|
|
|
|
2014-01-05 08:53:27 -06:00
|
|
|
// the forward Iterator impl.
|
2014-01-06 09:09:07 -06:00
|
|
|
item!(impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $name<'a, K, V> {
|
2014-01-05 08:53:27 -06:00
|
|
|
/// 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`.
|
2014-01-06 09:09:07 -06:00
|
|
|
fn next(&mut self) -> Option<(&'a K, &'a $($addr_mut)* V)> {
|
2014-01-05 08:53:27 -06:00
|
|
|
self.next_(true)
|
|
|
|
}
|
2014-01-05 07:40:53 -06:00
|
|
|
|
2014-01-05 08:53:27 -06:00
|
|
|
#[inline]
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
(self.remaining_min, Some(self.remaining_max))
|
|
|
|
}
|
2014-01-06 09:09:07 -06:00
|
|
|
})
|
2014-01-05 07:40:53 -06:00
|
|
|
|
2014-01-05 08:53:27 -06:00
|
|
|
// the reverse Iterator impl.
|
2014-01-06 09:09:07 -06:00
|
|
|
item!(impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $rev_name<'a, K, V> {
|
|
|
|
fn next(&mut self) -> Option<(&'a K, &'a $($addr_mut)* V)> {
|
2014-01-05 08:53:27 -06:00
|
|
|
self.iter.next_(false)
|
|
|
|
}
|
2014-01-05 07:40:53 -06:00
|
|
|
|
2014-01-05 08:53:27 -06:00
|
|
|
#[inline]
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
self.iter.size_hint()
|
|
|
|
}
|
2014-01-06 09:09:07 -06:00
|
|
|
})
|
2014-01-05 07:40:53 -06:00
|
|
|
}
|
2014-01-05 08:53:27 -06:00
|
|
|
} // end of define_iterator
|
2014-01-05 07:40:53 -06:00
|
|
|
|
2014-01-05 08:53:27 -06:00
|
|
|
define_iterator! {
|
2014-01-14 21:32:24 -06:00
|
|
|
Entries,
|
|
|
|
RevEntries,
|
2014-01-05 08:53:27 -06:00
|
|
|
deref = deref,
|
|
|
|
|
|
|
|
// immutable, so no mut
|
|
|
|
addr_mut =
|
2014-01-05 07:40:53 -06:00
|
|
|
}
|
2014-01-05 08:53:27 -06:00
|
|
|
define_iterator! {
|
2014-01-14 21:32:24 -06:00
|
|
|
MutEntries,
|
|
|
|
RevMutEntries,
|
2014-01-05 08:53:27 -06:00
|
|
|
deref = mut_deref,
|
2014-01-05 07:40:53 -06:00
|
|
|
|
2014-01-05 08:53:27 -06:00
|
|
|
addr_mut = mut
|
2014-01-05 07:40:53 -06:00
|
|
|
}
|
|
|
|
|
2014-06-25 14:47:34 -05:00
|
|
|
fn deref<'a, K, V>(node: &'a Option<Box<TreeNode<K, V>>>) -> *const TreeNode<K, V> {
|
2014-01-05 08:53:27 -06:00
|
|
|
match *node {
|
|
|
|
Some(ref n) => {
|
2014-07-07 18:35:15 -05:00
|
|
|
let n: &TreeNode<K, V> = &**n;
|
2014-06-25 14:47:34 -05:00
|
|
|
n as *const TreeNode<K, V>
|
2014-01-05 08:53:27 -06:00
|
|
|
}
|
|
|
|
None => ptr::null()
|
|
|
|
}
|
2014-01-05 07:40:53 -06:00
|
|
|
}
|
|
|
|
|
2014-05-05 20:56:44 -05:00
|
|
|
fn mut_deref<K, V>(x: &mut Option<Box<TreeNode<K, V>>>)
|
|
|
|
-> *mut TreeNode<K, V> {
|
2014-01-05 08:53:27 -06:00
|
|
|
match *x {
|
|
|
|
Some(ref mut n) => {
|
2014-06-25 01:11:57 -05:00
|
|
|
let n: &mut TreeNode<K, V> = &mut **n;
|
2014-01-05 08:53:27 -06:00
|
|
|
n as *mut TreeNode<K, V>
|
2014-01-05 07:40:53 -06:00
|
|
|
}
|
2014-01-05 08:53:27 -06:00
|
|
|
None => ptr::mut_null()
|
2014-01-05 07:40:53 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-07-18 14:37:18 -05:00
|
|
|
/// Lazy forward iterator over a map that consumes the map while iterating
|
2014-01-14 21:32:24 -06:00
|
|
|
pub struct MoveEntries<K, V> {
|
2014-04-05 00:45:42 -05:00
|
|
|
stack: Vec<TreeNode<K, V>>,
|
2014-03-27 17:10:04 -05:00
|
|
|
remaining: uint
|
2013-07-18 14:37:18 -05:00
|
|
|
}
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
impl<K, V> Iterator<(K, V)> for MoveEntries<K,V> {
|
2013-07-18 14:37:18 -05:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<(K, V)> {
|
|
|
|
while !self.stack.is_empty() {
|
|
|
|
let TreeNode {
|
|
|
|
key: key,
|
|
|
|
value: value,
|
|
|
|
left: left,
|
|
|
|
right: right,
|
|
|
|
level: level
|
2013-12-23 09:20:52 -06:00
|
|
|
} = self.stack.pop().unwrap();
|
2013-07-18 14:37:18 -05:00
|
|
|
|
|
|
|
match left {
|
2014-05-05 20:56:44 -05:00
|
|
|
Some(box left) => {
|
2013-07-18 14:37:18 -05:00
|
|
|
let n = TreeNode {
|
|
|
|
key: key,
|
|
|
|
value: value,
|
|
|
|
left: None,
|
|
|
|
right: right,
|
|
|
|
level: level
|
|
|
|
};
|
|
|
|
self.stack.push(n);
|
|
|
|
self.stack.push(left);
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
match right {
|
2014-05-05 20:56:44 -05:00
|
|
|
Some(box right) => self.stack.push(right),
|
2013-07-18 14:37:18 -05:00
|
|
|
None => ()
|
|
|
|
}
|
|
|
|
self.remaining -= 1;
|
|
|
|
return Some((key, value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
(self.remaining, Some(self.remaining))
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
impl<'a, T> Iterator<&'a T> for SetItems<'a, T> {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
fn next(&mut self) -> Option<&'a T> {
|
2013-11-20 17:46:49 -06:00
|
|
|
self.iter.next().map(|(value, _)| value)
|
2013-02-26 13:15:08 -06:00
|
|
|
}
|
2013-01-14 19:41:11 -06:00
|
|
|
}
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
impl<'a, T> Iterator<&'a T> for RevSetItems<'a, T> {
|
2013-08-06 14:57:46 -05:00
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
fn next(&mut self) -> Option<&'a T> {
|
2013-11-20 17:46:49 -06:00
|
|
|
self.iter.next().map(|(value, _)| value)
|
2013-08-06 14:57:46 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-28 22:11:41 -05:00
|
|
|
/// A implementation of the `Set` trait on top of the `TreeMap` container. The
|
|
|
|
/// only requirement is that the type of the elements contained ascribes to the
|
2014-05-31 12:43:52 -05:00
|
|
|
/// `Ord` trait.
|
2014-07-16 17:11:40 -05:00
|
|
|
///
|
|
|
|
/// ## Example
|
|
|
|
///
|
|
|
|
/// ```{rust}
|
|
|
|
/// use std::collections::TreeSet;
|
|
|
|
///
|
|
|
|
/// let mut tree_set = TreeSet::new();
|
|
|
|
///
|
|
|
|
/// tree_set.insert(2i);
|
|
|
|
/// tree_set.insert(1i);
|
|
|
|
/// tree_set.insert(3i);
|
|
|
|
///
|
|
|
|
/// for i in tree_set.iter() {
|
|
|
|
/// println!("{}", i) // prints 1, then 2, then 3
|
|
|
|
/// }
|
|
|
|
/// ```
|
2014-01-13 02:25:30 -06:00
|
|
|
#[deriving(Clone)]
|
2013-01-28 12:46:43 -06:00
|
|
|
pub struct TreeSet<T> {
|
2014-03-27 17:10:04 -05:00
|
|
|
map: TreeMap<T, ()>
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<T: PartialEq + Ord> PartialEq for TreeSet<T> {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:34:30 -05:00
|
|
|
fn eq(&self, other: &TreeSet<T>) -> bool { self.map == other.map }
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
|
|
|
|
2014-06-18 01:25:51 -05:00
|
|
|
impl<T: Ord> PartialOrd for TreeSet<T> {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2014-06-18 01:25:51 -05:00
|
|
|
fn partial_cmp(&self, other: &TreeSet<T>) -> Option<Ordering> {
|
|
|
|
self.map.partial_cmp(&other.map)
|
|
|
|
}
|
2013-01-26 11:40:41 -06:00
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<T: Ord + Show> Show for TreeSet<T> {
|
2014-05-28 11:24:28 -05:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
try!(write!(f, "{{"));
|
|
|
|
|
|
|
|
for (i, x) in self.iter().enumerate() {
|
|
|
|
if i != 0 { try!(write!(f, ", ")); }
|
|
|
|
try!(write!(f, "{}", *x));
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, "}}")
|
|
|
|
}
|
2014-05-27 12:38:52 -05:00
|
|
|
}
|
|
|
|
|
2014-05-19 13:32:09 -05:00
|
|
|
impl<T: Ord> Collection for TreeSet<T> {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-06-23 22:44:11 -05:00
|
|
|
fn len(&self) -> uint { self.map.len() }
|
2013-01-21 20:59:19 -06:00
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<T: Ord> Mutable for TreeSet<T> {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-01-21 16:25:57 -06:00
|
|
|
fn clear(&mut self) { self.map.clear() }
|
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<T: Ord> Set<T> for TreeSet<T> {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:34:30 -05:00
|
|
|
fn contains(&self, value: &T) -> bool {
|
2013-01-20 12:46:06 -06:00
|
|
|
self.map.contains_key(value)
|
|
|
|
}
|
|
|
|
|
2013-03-21 23:34:30 -05:00
|
|
|
fn is_disjoint(&self, other: &TreeSet<T>) -> bool {
|
2013-08-06 13:17:06 -05:00
|
|
|
self.intersection(other).next().is_none()
|
2013-01-29 16:04:25 -06:00
|
|
|
}
|
|
|
|
|
2013-03-21 23:34:30 -05:00
|
|
|
fn is_subset(&self, other: &TreeSet<T>) -> bool {
|
2013-01-29 15:07:11 -06:00
|
|
|
let mut x = self.iter();
|
|
|
|
let mut y = other.iter();
|
2013-04-09 09:54:32 -05:00
|
|
|
let mut a = x.next();
|
|
|
|
let mut b = y.next();
|
2014-04-13 22:22:58 -05:00
|
|
|
while a.is_some() {
|
|
|
|
if b.is_none() {
|
|
|
|
return false;
|
2013-03-22 17:07:09 -05:00
|
|
|
}
|
2013-01-29 15:07:11 -06:00
|
|
|
|
2013-03-22 17:07:09 -05:00
|
|
|
let a1 = a.unwrap();
|
|
|
|
let b1 = b.unwrap();
|
2013-01-29 15:07:11 -06:00
|
|
|
|
2014-04-13 22:22:58 -05:00
|
|
|
match b1.cmp(a1) {
|
|
|
|
Less => (),
|
|
|
|
Greater => return false,
|
|
|
|
Equal => a = x.next(),
|
2013-01-29 15:07:11 -06:00
|
|
|
}
|
2013-03-22 17:07:09 -05:00
|
|
|
|
2014-04-13 22:22:58 -05:00
|
|
|
b = y.next();
|
2013-01-29 15:07:11 -06:00
|
|
|
}
|
|
|
|
true
|
|
|
|
}
|
2013-07-31 14:07:45 -05:00
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<T: Ord> MutableSet<T> for TreeSet<T> {
|
2013-07-31 14:07:45 -05:00
|
|
|
#[inline]
|
|
|
|
fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
|
|
|
|
}
|
|
|
|
|
2014-06-09 02:30:04 -05:00
|
|
|
impl<T: Ord> Default for TreeSet<T> {
|
|
|
|
#[inline]
|
|
|
|
fn default() -> TreeSet<T> { TreeSet::new() }
|
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<T: Ord> TreeSet<T> {
|
2013-07-31 14:07:45 -05:00
|
|
|
/// Create an empty TreeSet
|
|
|
|
#[inline]
|
|
|
|
pub fn new() -> TreeSet<T> { TreeSet{map: TreeMap::new()} }
|
|
|
|
|
|
|
|
/// Get a lazy iterator over the values in the set.
|
|
|
|
/// Requires that it be frozen (immutable).
|
|
|
|
#[inline]
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn iter<'a>(&'a self) -> SetItems<'a, T> {
|
|
|
|
SetItems{iter: self.map.iter()}
|
2013-07-31 14:07:45 -05:00
|
|
|
}
|
|
|
|
|
2013-08-06 14:57:46 -05:00
|
|
|
/// Get a lazy iterator over the values in the set.
|
|
|
|
/// Requires that it be frozen (immutable).
|
|
|
|
#[inline]
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn rev_iter<'a>(&'a self) -> RevSetItems<'a, T> {
|
|
|
|
RevSetItems{iter: self.map.rev_iter()}
|
2013-08-06 14:57:46 -05:00
|
|
|
}
|
|
|
|
|
2014-05-11 21:34:44 -05:00
|
|
|
/// Get a lazy iterator that consumes the set.
|
|
|
|
#[inline]
|
|
|
|
pub fn move_iter(self) -> MoveSetItems<T> {
|
|
|
|
self.map.move_iter().map(|(value, _)| value)
|
|
|
|
}
|
|
|
|
|
2013-08-01 15:59:07 -05:00
|
|
|
/// Get a lazy iterator pointing to the first value not less than `v` (greater or equal).
|
|
|
|
/// If all elements in the set are less than `v` empty iterator is returned.
|
|
|
|
#[inline]
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn lower_bound<'a>(&'a self, v: &T) -> SetItems<'a, T> {
|
|
|
|
SetItems{iter: self.map.lower_bound(v)}
|
2013-08-01 15:59:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get a lazy iterator pointing to the first value greater than `v`.
|
|
|
|
/// If all elements in the set are not greater than `v` empty iterator is returned.
|
|
|
|
#[inline]
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn upper_bound<'a>(&'a self, v: &T) -> SetItems<'a, T> {
|
|
|
|
SetItems{iter: self.map.upper_bound(v)}
|
2013-08-01 15:59:07 -05:00
|
|
|
}
|
|
|
|
|
2013-01-14 09:27:26 -06:00
|
|
|
/// Visit the values (in-order) representing the difference
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn difference<'a>(&'a self, other: &'a TreeSet<T>) -> DifferenceItems<'a, T> {
|
|
|
|
DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()}
|
2013-08-06 13:17:06 -05:00
|
|
|
}
|
2013-05-02 17:33:27 -05:00
|
|
|
|
2013-08-06 13:17:06 -05:00
|
|
|
/// Visit the values (in-order) representing the symmetric difference
|
|
|
|
pub fn symmetric_difference<'a>(&'a self, other: &'a TreeSet<T>)
|
2014-01-14 21:32:24 -06:00
|
|
|
-> SymDifferenceItems<'a, T> {
|
|
|
|
SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()}
|
2013-08-06 13:17:06 -05:00
|
|
|
}
|
2013-05-02 17:33:27 -05:00
|
|
|
|
2013-08-06 13:17:06 -05:00
|
|
|
/// Visit the values (in-order) representing the intersection
|
|
|
|
pub fn intersection<'a>(&'a self, other: &'a TreeSet<T>)
|
2014-01-14 21:32:24 -06:00
|
|
|
-> IntersectionItems<'a, T> {
|
|
|
|
IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()}
|
2013-08-06 13:17:06 -05:00
|
|
|
}
|
2013-05-02 17:33:27 -05:00
|
|
|
|
2013-08-06 13:17:06 -05:00
|
|
|
/// Visit the values (in-order) representing the union
|
2014-01-14 21:32:24 -06:00
|
|
|
pub fn union<'a>(&'a self, other: &'a TreeSet<T>) -> UnionItems<'a, T> {
|
|
|
|
UnionItems{a: self.iter().peekable(), b: other.iter().peekable()}
|
2013-08-06 13:17:06 -05:00
|
|
|
}
|
|
|
|
}
|
2013-05-02 17:33:27 -05:00
|
|
|
|
2013-08-06 13:17:06 -05:00
|
|
|
/// Lazy forward iterator over a set
|
2014-01-14 21:32:24 -06:00
|
|
|
pub struct SetItems<'a, T> {
|
2014-03-27 17:10:04 -05:00
|
|
|
iter: Entries<'a, T, ()>
|
2013-08-06 13:17:06 -05:00
|
|
|
}
|
2013-05-02 17:33:27 -05:00
|
|
|
|
2013-08-06 14:57:46 -05:00
|
|
|
/// Lazy backward iterator over a set
|
2014-01-14 21:32:24 -06:00
|
|
|
pub struct RevSetItems<'a, T> {
|
2014-03-27 17:10:04 -05:00
|
|
|
iter: RevEntries<'a, T, ()>
|
2013-08-06 14:57:46 -05:00
|
|
|
}
|
|
|
|
|
2014-05-11 21:34:44 -05:00
|
|
|
/// Lazy forward iterator over a set that consumes the set while iterating
|
|
|
|
pub type MoveSetItems<T> = iter::Map<'static, (T, ()), T, MoveEntries<T, ()>>;
|
|
|
|
|
2013-08-06 13:17:06 -05:00
|
|
|
/// Lazy iterator producing elements in the set difference (in-order)
|
2014-01-14 21:32:24 -06:00
|
|
|
pub struct DifferenceItems<'a, T> {
|
2014-03-27 17:10:04 -05:00
|
|
|
a: Peekable<&'a T, SetItems<'a, T>>,
|
|
|
|
b: Peekable<&'a T, SetItems<'a, T>>,
|
2013-08-06 13:17:06 -05:00
|
|
|
}
|
2013-05-02 17:33:27 -05:00
|
|
|
|
2013-08-06 13:17:06 -05:00
|
|
|
/// Lazy iterator producing elements in the set symmetric difference (in-order)
|
2014-01-14 21:32:24 -06:00
|
|
|
pub struct SymDifferenceItems<'a, T> {
|
2014-03-27 17:10:04 -05:00
|
|
|
a: Peekable<&'a T, SetItems<'a, T>>,
|
|
|
|
b: Peekable<&'a T, SetItems<'a, T>>,
|
2013-08-06 13:17:06 -05:00
|
|
|
}
|
2013-05-02 17:33:27 -05:00
|
|
|
|
2013-08-06 13:17:06 -05:00
|
|
|
/// Lazy iterator producing elements in the set intersection (in-order)
|
2014-01-14 21:32:24 -06:00
|
|
|
pub struct IntersectionItems<'a, T> {
|
2014-03-27 17:10:04 -05:00
|
|
|
a: Peekable<&'a T, SetItems<'a, T>>,
|
|
|
|
b: Peekable<&'a T, SetItems<'a, T>>,
|
2013-08-06 13:17:06 -05:00
|
|
|
}
|
2013-05-02 17:33:27 -05:00
|
|
|
|
2014-06-12 01:36:46 -05:00
|
|
|
/// Lazy iterator producing elements in the set union (in-order)
|
2014-01-14 21:32:24 -06:00
|
|
|
pub struct UnionItems<'a, T> {
|
2014-03-27 17:10:04 -05:00
|
|
|
a: Peekable<&'a T, SetItems<'a, T>>,
|
|
|
|
b: Peekable<&'a T, SetItems<'a, T>>,
|
2013-08-09 16:31:57 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None
|
2014-05-31 12:43:52 -05:00
|
|
|
fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>,
|
2013-08-09 16:31:57 -05:00
|
|
|
short: Ordering, long: Ordering) -> Ordering {
|
|
|
|
match (x, y) {
|
|
|
|
(None , _ ) => short,
|
|
|
|
(_ , None ) => long,
|
|
|
|
(Some(x1), Some(y1)) => x1.cmp(y1),
|
|
|
|
}
|
2013-08-06 13:17:06 -05:00
|
|
|
}
|
2013-05-02 17:33:27 -05:00
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<'a, T: Ord> Iterator<&'a T> for DifferenceItems<'a, T> {
|
2013-12-10 01:16:18 -06:00
|
|
|
fn next(&mut self) -> Option<&'a T> {
|
2013-08-06 13:17:06 -05:00
|
|
|
loop {
|
2013-08-09 16:31:57 -05:00
|
|
|
match cmp_opt(self.a.peek(), self.b.peek(), Less, Less) {
|
|
|
|
Less => return self.a.next(),
|
|
|
|
Equal => { self.a.next(); self.b.next(); }
|
|
|
|
Greater => { self.b.next(); }
|
2013-05-02 17:33:27 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-08-06 13:17:06 -05:00
|
|
|
}
|
2013-01-14 09:27:26 -06:00
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<'a, T: Ord> Iterator<&'a T> for SymDifferenceItems<'a, T> {
|
2013-12-10 01:16:18 -06:00
|
|
|
fn next(&mut self) -> Option<&'a T> {
|
2013-08-06 13:17:06 -05:00
|
|
|
loop {
|
2013-08-09 16:31:57 -05:00
|
|
|
match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
|
|
|
|
Less => return self.a.next(),
|
|
|
|
Equal => { self.a.next(); self.b.next(); }
|
|
|
|
Greater => return self.b.next(),
|
2013-05-02 17:33:27 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-08-06 13:17:06 -05:00
|
|
|
}
|
2013-01-14 09:27:26 -06:00
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<'a, T: Ord> Iterator<&'a T> for IntersectionItems<'a, T> {
|
2013-12-10 01:16:18 -06:00
|
|
|
fn next(&mut self) -> Option<&'a T> {
|
2013-08-06 13:17:06 -05:00
|
|
|
loop {
|
2013-08-09 16:31:57 -05:00
|
|
|
let o_cmp = match (self.a.peek(), self.b.peek()) {
|
|
|
|
(None , _ ) => None,
|
|
|
|
(_ , None ) => None,
|
|
|
|
(Some(a1), Some(b1)) => Some(a1.cmp(b1)),
|
|
|
|
};
|
|
|
|
match o_cmp {
|
|
|
|
None => return None,
|
|
|
|
Some(Less) => { self.a.next(); }
|
|
|
|
Some(Equal) => { self.b.next(); return self.a.next() }
|
|
|
|
Some(Greater) => { self.b.next(); }
|
2013-05-02 17:33:27 -05:00
|
|
|
}
|
2013-08-06 13:17:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-05-02 17:33:27 -05:00
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<'a, T: Ord> Iterator<&'a T> for UnionItems<'a, T> {
|
2013-12-10 01:16:18 -06:00
|
|
|
fn next(&mut self) -> Option<&'a T> {
|
2013-08-06 13:17:06 -05:00
|
|
|
loop {
|
2013-08-09 16:31:57 -05:00
|
|
|
match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
|
|
|
|
Less => return self.a.next(),
|
|
|
|
Equal => { self.b.next(); return self.a.next() }
|
|
|
|
Greater => return self.b.next(),
|
2013-05-02 17:33:27 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-08-26 12:50:02 -05:00
|
|
|
}
|
2012-01-17 21:05:07 -06:00
|
|
|
|
2013-01-15 13:25:37 -06:00
|
|
|
|
2013-01-14 09:27:26 -06:00
|
|
|
// 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.
|
2013-07-17 17:15:34 -05:00
|
|
|
#[deriving(Clone)]
|
2013-01-28 12:46:43 -06:00
|
|
|
struct TreeNode<K, V> {
|
2013-01-14 09:27:26 -06:00
|
|
|
key: K,
|
|
|
|
value: V,
|
2014-05-05 20:56:44 -05:00
|
|
|
left: Option<Box<TreeNode<K, V>>>,
|
|
|
|
right: Option<Box<TreeNode<K, V>>>,
|
2013-01-14 09:27:26 -06:00
|
|
|
level: uint
|
2012-10-04 17:18:02 -05:00
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<K: Ord, V> TreeNode<K, V> {
|
2013-05-31 17:17:22 -05:00
|
|
|
/// Creates a new tree node.
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-31 17:17:22 -05:00
|
|
|
pub fn new(key: K, value: V) -> TreeNode<K, V> {
|
2013-01-14 09:27:26 -06:00
|
|
|
TreeNode{key: key, value: value, left: None, right: None, level: 1}
|
|
|
|
}
|
|
|
|
}
|
2012-10-04 17:18:02 -05:00
|
|
|
|
2013-01-14 09:27:26 -06:00
|
|
|
// Remove left horizontal link by rotating right
|
2014-05-31 12:43:52 -05:00
|
|
|
fn skew<K: Ord, V>(node: &mut Box<TreeNode<K, V>>) {
|
2013-12-06 12:51:10 -06:00
|
|
|
if node.left.as_ref().map_or(false, |x| x.level == node.level) {
|
2013-07-16 14:47:01 -05:00
|
|
|
let mut save = node.left.take_unwrap();
|
2013-05-05 23:42:54 -05:00
|
|
|
swap(&mut node.left, &mut save.right); // save.right now None
|
|
|
|
swap(node, &mut save);
|
2013-02-10 19:37:21 -06:00
|
|
|
node.right = Some(save);
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove dual horizontal link by rotating left and increasing level of
|
|
|
|
// the parent
|
2014-05-31 12:43:52 -05:00
|
|
|
fn split<K: Ord, V>(node: &mut Box<TreeNode<K, V>>) {
|
2013-12-06 12:51:10 -06:00
|
|
|
if node.right.as_ref().map_or(false,
|
|
|
|
|x| x.right.as_ref().map_or(false, |y| y.level == node.level)) {
|
2013-07-16 14:47:01 -05:00
|
|
|
let mut save = node.right.take_unwrap();
|
2013-05-05 23:42:54 -05:00
|
|
|
swap(&mut node.right, &mut save.left); // save.left now None
|
2013-01-14 09:27:26 -06:00
|
|
|
save.level += 1;
|
2013-05-05 23:42:54 -05:00
|
|
|
swap(node, &mut save);
|
2013-02-10 19:37:21 -06:00
|
|
|
node.left = Some(save);
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-09 09:48:17 -05:00
|
|
|
// Next 2 functions have the same conventions
|
|
|
|
//
|
|
|
|
// The only difference is that non-mutable version uses loop instead
|
|
|
|
// of recursion (performance considerations)
|
|
|
|
// It seems to be impossible to avoid recursion with mutability
|
|
|
|
//
|
|
|
|
// So convention is that comparator is gets at input current key
|
|
|
|
// and returns search_key cmp cur_key (i.e. search_key.cmp(cur_key))
|
|
|
|
fn tree_find_with<'r, K, V>(node: &'r Option<Box<TreeNode<K, V>>>,
|
|
|
|
f: |&K| -> Ordering) -> Option<&'r V> {
|
|
|
|
let mut current: &'r Option<Box<TreeNode<K, V>>> = node;
|
|
|
|
loop {
|
|
|
|
match *current {
|
|
|
|
Some(ref r) => {
|
|
|
|
match f(&r.key) {
|
|
|
|
Less => current = &r.left,
|
|
|
|
Greater => current = &r.right,
|
|
|
|
Equal => return Some(&r.value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => return None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// See comments above tree_find_with
|
|
|
|
fn tree_find_mut_with<'r, K, V>(node: &'r mut Option<Box<TreeNode<K, V>>>,
|
|
|
|
f: |&K| -> Ordering) -> Option<&'r mut V> {
|
|
|
|
|
|
|
|
let mut current = node;
|
|
|
|
loop {
|
|
|
|
let temp = current; // hack to appease borrowck
|
|
|
|
match *temp {
|
|
|
|
Some(ref mut r) => {
|
|
|
|
match f(&r.key) {
|
|
|
|
Less => current = &mut r.left,
|
|
|
|
Greater => current = &mut r.right,
|
|
|
|
Equal => return Some(&mut r.value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => return None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
fn insert<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
|
2013-05-04 08:54:58 -05:00
|
|
|
key: K, value: V) -> Option<V> {
|
2013-02-10 19:44:15 -06:00
|
|
|
match *node {
|
|
|
|
Some(ref mut save) => {
|
2013-03-02 12:27:29 -06:00
|
|
|
match key.cmp(&save.key) {
|
|
|
|
Less => {
|
2013-01-14 09:27:26 -06:00
|
|
|
let inserted = insert(&mut save.left, key, value);
|
2013-02-10 19:44:15 -06:00
|
|
|
skew(save);
|
|
|
|
split(save);
|
2013-01-14 09:27:26 -06:00
|
|
|
inserted
|
2013-03-02 12:27:29 -06:00
|
|
|
}
|
|
|
|
Greater => {
|
2013-01-14 09:27:26 -06:00
|
|
|
let inserted = insert(&mut save.right, key, value);
|
2013-02-10 19:44:15 -06:00
|
|
|
skew(save);
|
|
|
|
split(save);
|
2013-01-14 09:27:26 -06:00
|
|
|
inserted
|
2013-03-02 12:27:29 -06:00
|
|
|
}
|
|
|
|
Equal => {
|
2013-01-14 09:27:26 -06:00
|
|
|
save.key = key;
|
2013-05-04 08:54:58 -05:00
|
|
|
Some(replace(&mut save.value, value))
|
2013-03-02 12:27:29 -06:00
|
|
|
}
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
2013-02-10 19:44:15 -06:00
|
|
|
}
|
|
|
|
None => {
|
2014-04-25 03:08:02 -05:00
|
|
|
*node = Some(box TreeNode::new(key, value));
|
2013-05-04 08:54:58 -05:00
|
|
|
None
|
2013-02-10 19:44:15 -06:00
|
|
|
}
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
fn remove<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
|
2013-05-04 08:54:58 -05:00
|
|
|
key: &K) -> Option<V> {
|
2014-05-31 12:43:52 -05:00
|
|
|
fn heir_swap<K: Ord, V>(node: &mut Box<TreeNode<K, V>>,
|
2014-05-05 20:56:44 -05:00
|
|
|
child: &mut Option<Box<TreeNode<K, V>>>) {
|
2013-01-14 09:27:26 -06:00
|
|
|
// *could* be done without recursion, but it won't borrow check
|
2013-08-03 11:45:23 -05:00
|
|
|
for x in child.mut_iter() {
|
2013-03-15 13:14:03 -05:00
|
|
|
if x.right.is_some() {
|
|
|
|
heir_swap(node, &mut x.right);
|
2013-01-14 09:27:26 -06:00
|
|
|
} else {
|
2013-05-05 23:42:54 -05:00
|
|
|
swap(&mut node.key, &mut x.key);
|
|
|
|
swap(&mut node.value, &mut x.value);
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-10 21:03:26 -06:00
|
|
|
match *node {
|
|
|
|
None => {
|
2013-05-04 08:54:58 -05:00
|
|
|
return None; // bottom of tree
|
2013-02-10 21:03:26 -06:00
|
|
|
}
|
|
|
|
Some(ref mut save) => {
|
2013-05-04 08:54:58 -05:00
|
|
|
let (ret, rebalance) = match key.cmp(&save.key) {
|
|
|
|
Less => (remove(&mut save.left, key), true),
|
|
|
|
Greater => (remove(&mut save.right, key), true),
|
2013-03-02 12:27:29 -06:00
|
|
|
Equal => {
|
2013-01-14 09:27:26 -06:00
|
|
|
if save.left.is_some() {
|
|
|
|
if save.right.is_some() {
|
2013-07-16 14:47:01 -05:00
|
|
|
let mut left = save.left.take_unwrap();
|
2013-01-14 09:27:26 -06:00
|
|
|
if left.right.is_some() {
|
|
|
|
heir_swap(save, &mut left.right);
|
|
|
|
} else {
|
2013-05-05 23:42:54 -05:00
|
|
|
swap(&mut save.key, &mut left.key);
|
|
|
|
swap(&mut save.value, &mut left.value);
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
2013-01-29 14:48:18 -06:00
|
|
|
save.left = Some(left);
|
2013-05-04 08:54:58 -05:00
|
|
|
(remove(&mut save.left, key), true)
|
2013-01-14 09:27:26 -06:00
|
|
|
} else {
|
2013-07-16 14:47:01 -05:00
|
|
|
let new = save.left.take_unwrap();
|
2014-05-05 20:56:44 -05:00
|
|
|
let box TreeNode{value, ..} = replace(save, new);
|
2013-07-16 14:47:01 -05:00
|
|
|
*save = save.left.take_unwrap();
|
2013-05-04 08:54:58 -05:00
|
|
|
(Some(value), true)
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
|
|
|
} else if save.right.is_some() {
|
2013-07-16 14:47:01 -05:00
|
|
|
let new = save.right.take_unwrap();
|
2014-05-05 20:56:44 -05:00
|
|
|
let box TreeNode{value, ..} = replace(save, new);
|
2013-05-04 08:54:58 -05:00
|
|
|
(Some(value), true)
|
2013-01-14 09:27:26 -06:00
|
|
|
} else {
|
2013-05-04 08:54:58 -05:00
|
|
|
(None, false)
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
2013-03-02 12:27:29 -06:00
|
|
|
}
|
2013-01-14 09:27:26 -06:00
|
|
|
};
|
|
|
|
|
2013-05-04 08:54:58 -05:00
|
|
|
if rebalance {
|
2013-12-06 12:51:10 -06:00
|
|
|
let left_level = save.left.as_ref().map_or(0, |x| x.level);
|
|
|
|
let right_level = save.right.as_ref().map_or(0, |x| x.level);
|
2013-02-10 21:03:26 -06:00
|
|
|
|
2013-02-09 00:21:45 -06:00
|
|
|
// re-balance, if necessary
|
|
|
|
if left_level < save.level - 1 || right_level < save.level - 1 {
|
|
|
|
save.level -= 1;
|
2013-01-14 09:27:26 -06:00
|
|
|
|
2013-02-09 00:21:45 -06:00
|
|
|
if right_level > save.level {
|
2013-08-03 11:45:23 -05:00
|
|
|
for x in save.right.mut_iter() { x.level = save.level }
|
2013-02-09 00:21:45 -06:00
|
|
|
}
|
2013-01-14 09:27:26 -06:00
|
|
|
|
2013-02-09 00:21:45 -06:00
|
|
|
skew(save);
|
2013-01-14 09:27:26 -06:00
|
|
|
|
2013-08-03 11:45:23 -05:00
|
|
|
for right in save.right.mut_iter() {
|
2013-03-10 18:59:41 -05:00
|
|
|
skew(right);
|
2013-08-03 11:45:23 -05:00
|
|
|
for x in right.right.mut_iter() { skew(x) }
|
2013-02-09 00:21:45 -06:00
|
|
|
}
|
2013-02-10 19:37:21 -06:00
|
|
|
|
2013-02-09 00:21:45 -06:00
|
|
|
split(save);
|
2013-08-03 11:45:23 -05:00
|
|
|
for x in save.right.mut_iter() { split(x) }
|
2013-02-10 19:37:21 -06:00
|
|
|
}
|
2013-01-14 09:27:26 -06:00
|
|
|
|
2013-05-04 08:54:58 -05:00
|
|
|
return ret;
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
2013-02-10 21:03:26 -06:00
|
|
|
}
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
2013-07-17 16:41:50 -05:00
|
|
|
return match node.take() {
|
2014-05-05 20:56:44 -05:00
|
|
|
Some(box TreeNode{value, ..}) => Some(value), None => fail!()
|
2013-05-04 08:54:58 -05:00
|
|
|
};
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
2013-01-08 21:37:25 -06:00
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<K: Ord, V> FromIterator<(K, V)> for TreeMap<K, V> {
|
2014-03-30 23:45:55 -05:00
|
|
|
fn from_iter<T: Iterator<(K, V)>>(iter: T) -> TreeMap<K, V> {
|
2013-07-14 12:18:50 -05:00
|
|
|
let mut map = TreeMap::new();
|
2013-07-29 19:06:49 -05:00
|
|
|
map.extend(iter);
|
|
|
|
map
|
|
|
|
}
|
|
|
|
}
|
2013-07-14 12:18:50 -05:00
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<K: Ord, V> Extendable<(K, V)> for TreeMap<K, V> {
|
2013-07-29 19:06:49 -05:00
|
|
|
#[inline]
|
2014-03-20 08:12:56 -05:00
|
|
|
fn extend<T: Iterator<(K, V)>>(&mut self, mut iter: T) {
|
|
|
|
for (k, v) in iter {
|
2013-07-29 19:06:49 -05:00
|
|
|
self.insert(k, v);
|
2013-07-14 12:18:50 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-12 12:23:20 -05:00
|
|
|
impl<S: Writer, K: Ord + Hash<S>, V: Hash<S>> Hash<S> for TreeMap<K, V> {
|
|
|
|
fn hash(&self, state: &mut S) {
|
|
|
|
for elt in self.iter() {
|
|
|
|
elt.hash(state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<T: Ord> FromIterator<T> for TreeSet<T> {
|
2014-03-30 23:45:55 -05:00
|
|
|
fn from_iter<Iter: Iterator<T>>(iter: Iter) -> TreeSet<T> {
|
2013-07-14 12:18:50 -05:00
|
|
|
let mut set = TreeSet::new();
|
2013-07-29 19:06:49 -05:00
|
|
|
set.extend(iter);
|
|
|
|
set
|
|
|
|
}
|
|
|
|
}
|
2013-07-14 12:18:50 -05:00
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
impl<T: Ord> Extendable<T> for TreeSet<T> {
|
2013-07-29 19:06:49 -05:00
|
|
|
#[inline]
|
2014-03-20 08:12:56 -05:00
|
|
|
fn extend<Iter: Iterator<T>>(&mut self, mut iter: Iter) {
|
|
|
|
for elem in iter {
|
2013-07-29 19:06:49 -05:00
|
|
|
self.insert(elem);
|
2013-07-14 12:18:50 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-12 12:23:20 -05:00
|
|
|
impl<S: Writer, T: Ord + Hash<S>> Hash<S> for TreeSet<T> {
|
|
|
|
fn hash(&self, state: &mut S) {
|
|
|
|
for elt in self.iter() {
|
|
|
|
elt.hash(state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-14 09:27:26 -06:00
|
|
|
#[cfg(test)]
|
|
|
|
mod test_treemap {
|
2014-05-29 21:03:06 -05:00
|
|
|
use std::prelude::*;
|
std: Recreate a `rand` module
This commit shuffles around some of the `rand` code, along with some
reorganization. The new state of the world is as follows:
* The librand crate now only depends on libcore. This interface is experimental.
* The standard library has a new module, `std::rand`. This interface will
eventually become stable.
Unfortunately, this entailed more of a breaking change than just shuffling some
names around. The following breaking changes were made to the rand library:
* Rng::gen_vec() was removed. This has been replaced with Rng::gen_iter() which
will return an infinite stream of random values. Previous behavior can be
regained with `rng.gen_iter().take(n).collect()`
* Rng::gen_ascii_str() was removed. This has been replaced with
Rng::gen_ascii_chars() which will return an infinite stream of random ascii
characters. Similarly to gen_iter(), previous behavior can be emulated with
`rng.gen_ascii_chars().take(n).collect()`
* {IsaacRng, Isaac64Rng, XorShiftRng}::new() have all been removed. These all
relied on being able to use an OSRng for seeding, but this is no longer
available in librand (where these types are defined). To retain the same
functionality, these types now implement the `Rand` trait so they can be
generated with a random seed from another random number generator. This allows
the stdlib to use an OSRng to create seeded instances of these RNGs.
* Rand implementations for `Box<T>` and `@T` were removed. These seemed to be
pretty rare in the codebase, and it allows for librand to not depend on
liballoc. Additionally, other pointer types like Rc<T> and Arc<T> were not
supported. If this is undesirable, librand can depend on liballoc and regain
these implementations.
* The WeightedChoice structure is no longer built with a `Vec<Weighted<T>>`,
but rather a `&mut [Weighted<T>]`. This means that the WeightedChoice
structure now has a lifetime associated with it.
* The `sample` method on `Rng` has been moved to a top-level function in the
`rand` module due to its dependence on `Vec`.
cc #13851
[breaking-change]
2014-05-25 03:39:37 -05:00
|
|
|
use std::rand::Rng;
|
|
|
|
use std::rand;
|
2012-12-27 20:24:18 -06:00
|
|
|
|
2014-06-06 18:33:44 -05:00
|
|
|
use {Map, MutableMap, Mutable};
|
2014-05-29 21:03:06 -05:00
|
|
|
use super::{TreeMap, TreeNode};
|
|
|
|
|
2012-01-17 21:05:07 -06:00
|
|
|
#[test]
|
2013-01-14 09:27:26 -06:00
|
|
|
fn find_empty() {
|
2013-08-08 13:38:10 -05:00
|
|
|
let m: TreeMap<int,int> = TreeMap::new();
|
|
|
|
assert!(m.find(&5) == None);
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
2012-01-17 21:05:07 -06:00
|
|
|
|
|
|
|
#[test]
|
2013-01-14 09:27:26 -06:00
|
|
|
fn find_not_found() {
|
|
|
|
let mut m = TreeMap::new();
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(m.insert(1i, 2i));
|
|
|
|
assert!(m.insert(5i, 3i));
|
|
|
|
assert!(m.insert(9i, 3i));
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(m.find(&2), None);
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
2012-01-17 21:05:07 -06:00
|
|
|
|
2014-07-09 09:48:17 -05:00
|
|
|
#[test]
|
|
|
|
fn find_with_empty() {
|
|
|
|
let m: TreeMap<&'static str,int> = TreeMap::new();
|
|
|
|
assert!(m.find_with(|k| "test".cmp(k)) == None);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn find_with_not_found() {
|
|
|
|
let mut m = TreeMap::new();
|
|
|
|
assert!(m.insert("test1", 2i));
|
|
|
|
assert!(m.insert("test2", 3i));
|
|
|
|
assert!(m.insert("test3", 3i));
|
|
|
|
assert_eq!(m.find_with(|k| "test4".cmp(k)), None);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn find_with_found() {
|
|
|
|
let mut m = TreeMap::new();
|
|
|
|
assert!(m.insert("test1", 2i));
|
|
|
|
assert!(m.insert("test2", 3i));
|
|
|
|
assert!(m.insert("test3", 4i));
|
|
|
|
assert_eq!(m.find_with(|k| "test2".cmp(k)), Some(&3i));
|
|
|
|
}
|
|
|
|
|
2013-03-24 15:55:51 -05:00
|
|
|
#[test]
|
|
|
|
fn test_find_mut() {
|
|
|
|
let mut m = TreeMap::new();
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(m.insert(1i, 12i));
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(m.insert(2, 8));
|
|
|
|
assert!(m.insert(5, 14));
|
2013-03-24 15:55:51 -05:00
|
|
|
let new = 100;
|
|
|
|
match m.find_mut(&5) {
|
2013-10-21 15:08:31 -05:00
|
|
|
None => fail!(), Some(x) => *x = new
|
2013-03-24 15:55:51 -05:00
|
|
|
}
|
|
|
|
assert_eq!(m.find(&5), Some(&new));
|
|
|
|
}
|
|
|
|
|
2014-07-09 09:48:17 -05:00
|
|
|
#[test]
|
|
|
|
fn test_find_with_mut() {
|
|
|
|
let mut m = TreeMap::new();
|
|
|
|
assert!(m.insert("t1", 12i));
|
|
|
|
assert!(m.insert("t2", 8));
|
|
|
|
assert!(m.insert("t5", 14));
|
|
|
|
let new = 100;
|
|
|
|
match m.find_mut_with(|k| "t5".cmp(k)) {
|
|
|
|
None => fail!(), Some(x) => *x = new
|
|
|
|
}
|
|
|
|
assert_eq!(m.find_with(|k| "t5".cmp(k)), Some(&new));
|
|
|
|
}
|
|
|
|
|
2012-01-17 21:05:07 -06:00
|
|
|
#[test]
|
2013-01-14 09:27:26 -06:00
|
|
|
fn insert_replace() {
|
|
|
|
let mut m = TreeMap::new();
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(m.insert(5i, 2i));
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(m.insert(2, 9));
|
|
|
|
assert!(!m.insert(2, 11));
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(m.find(&2).unwrap(), &11);
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
2012-01-17 21:05:07 -06:00
|
|
|
|
2013-01-21 16:25:57 -06:00
|
|
|
#[test]
|
|
|
|
fn test_clear() {
|
|
|
|
let mut m = TreeMap::new();
|
|
|
|
m.clear();
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(m.insert(5i, 11i));
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(m.insert(12, -3));
|
|
|
|
assert!(m.insert(19, 2));
|
2013-01-21 16:25:57 -06:00
|
|
|
m.clear();
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(m.find(&5).is_none());
|
|
|
|
assert!(m.find(&12).is_none());
|
|
|
|
assert!(m.find(&19).is_none());
|
|
|
|
assert!(m.is_empty());
|
2013-01-21 16:25:57 -06:00
|
|
|
}
|
|
|
|
|
2012-01-17 21:05:07 -06:00
|
|
|
#[test]
|
2013-01-14 09:27:26 -06:00
|
|
|
fn u8_map() {
|
|
|
|
let mut m = TreeMap::new();
|
|
|
|
|
2013-06-10 22:10:37 -05:00
|
|
|
let k1 = "foo".as_bytes();
|
|
|
|
let k2 = "bar".as_bytes();
|
|
|
|
let v1 = "baz".as_bytes();
|
|
|
|
let v2 = "foobar".as_bytes();
|
2013-01-14 09:27:26 -06:00
|
|
|
|
2013-07-02 14:47:32 -05:00
|
|
|
m.insert(k1.clone(), v1.clone());
|
|
|
|
m.insert(k2.clone(), v2.clone());
|
2013-01-14 09:27:26 -06:00
|
|
|
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(m.find(&k2), Some(&v2));
|
|
|
|
assert_eq!(m.find(&k1), Some(&v1));
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
fn check_equal<K: PartialEq + Ord, V: PartialEq>(ctrl: &[(K, V)],
|
2013-03-02 12:27:29 -06:00
|
|
|
map: &TreeMap<K, V>) {
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(ctrl.is_empty(), map.is_empty());
|
2013-08-03 11:45:23 -05:00
|
|
|
for x in ctrl.iter() {
|
2013-06-20 14:15:16 -05:00
|
|
|
let &(ref k, ref v) = x;
|
|
|
|
assert!(map.find(k).unwrap() == v)
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
2013-08-03 11:45:23 -05:00
|
|
|
for (map_k, map_v) in map.iter() {
|
2013-01-14 09:27:26 -06:00
|
|
|
let mut found = false;
|
2013-08-03 11:45:23 -05:00
|
|
|
for x in ctrl.iter() {
|
2013-06-20 14:15:16 -05:00
|
|
|
let &(ref ctrl_k, ref ctrl_v) = x;
|
|
|
|
if *map_k == *ctrl_k {
|
|
|
|
assert!(*map_v == *ctrl_v);
|
2013-01-14 09:27:26 -06:00
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(found);
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
fn check_left<K: Ord, V>(node: &Option<Box<TreeNode<K, V>>>,
|
2014-05-05 20:56:44 -05:00
|
|
|
parent: &Box<TreeNode<K, V>>) {
|
2013-01-14 09:27:26 -06:00
|
|
|
match *node {
|
|
|
|
Some(ref r) => {
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(r.key.cmp(&parent.key), Less);
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(r.level == parent.level - 1); // left is black
|
2013-01-14 09:27:26 -06:00
|
|
|
check_left(&r.left, r);
|
|
|
|
check_right(&r.right, r, false);
|
|
|
|
}
|
2013-03-28 20:39:09 -05:00
|
|
|
None => assert!(parent.level == 1) // parent is leaf
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
fn check_right<K: Ord, V>(node: &Option<Box<TreeNode<K, V>>>,
|
2014-05-05 20:56:44 -05:00
|
|
|
parent: &Box<TreeNode<K, V>>,
|
2013-03-02 12:27:29 -06:00
|
|
|
parent_red: bool) {
|
2013-01-14 09:27:26 -06:00
|
|
|
match *node {
|
|
|
|
Some(ref r) => {
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(r.key.cmp(&parent.key), Greater);
|
2013-01-14 09:27:26 -06:00
|
|
|
let red = r.level == parent.level;
|
2013-03-28 20:39:09 -05:00
|
|
|
if parent_red { assert!(!red) } // no dual horizontal links
|
2013-03-06 21:09:17 -06:00
|
|
|
// Right red or black
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(red || r.level == parent.level - 1);
|
2013-01-14 09:27:26 -06:00
|
|
|
check_left(&r.left, r);
|
|
|
|
check_right(&r.right, r, red);
|
|
|
|
}
|
2013-03-28 20:39:09 -05:00
|
|
|
None => assert!(parent.level == 1) // parent is leaf
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
fn check_structure<K: Ord, V>(map: &TreeMap<K, V>) {
|
2013-01-14 09:27:26 -06:00
|
|
|
match map.root {
|
|
|
|
Some(ref r) => {
|
|
|
|
check_left(&r.left, r);
|
|
|
|
check_right(&r.right, r, false);
|
|
|
|
}
|
|
|
|
None => ()
|
|
|
|
}
|
2012-01-17 21:05:07 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-01-14 09:27:26 -06:00
|
|
|
fn test_rand_int() {
|
2013-08-08 13:38:10 -05:00
|
|
|
let mut map: TreeMap<int,int> = TreeMap::new();
|
2014-04-05 00:45:42 -05:00
|
|
|
let mut ctrl = vec![];
|
2013-01-14 09:27:26 -06:00
|
|
|
|
2014-04-05 00:45:42 -05:00
|
|
|
check_equal(ctrl.as_slice(), &map);
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(map.find(&5).is_none());
|
2013-01-14 09:27:26 -06:00
|
|
|
|
2013-09-29 10:29:28 -05:00
|
|
|
let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(&[42]);
|
2013-01-14 09:27:26 -06:00
|
|
|
|
2014-04-21 16:58:52 -05:00
|
|
|
for _ in range(0u, 3) {
|
|
|
|
for _ in range(0u, 90) {
|
2013-04-24 07:29:19 -05:00
|
|
|
let k = rng.gen();
|
|
|
|
let v = rng.gen();
|
2013-07-04 21:13:26 -05:00
|
|
|
if !ctrl.iter().any(|x| x == &(k, v)) {
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(map.insert(k, v));
|
2013-01-14 09:27:26 -06:00
|
|
|
ctrl.push((k, v));
|
|
|
|
check_structure(&map);
|
2014-04-05 00:45:42 -05:00
|
|
|
check_equal(ctrl.as_slice(), &map);
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
2014-01-29 18:20:34 -06:00
|
|
|
}
|
2013-01-14 09:27:26 -06:00
|
|
|
|
2014-04-21 16:58:52 -05:00
|
|
|
for _ in range(0u, 30) {
|
2013-10-10 04:18:07 -05:00
|
|
|
let r = rng.gen_range(0, ctrl.len());
|
2013-12-23 09:53:20 -06:00
|
|
|
let (key, _) = ctrl.remove(r).unwrap();
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(map.remove(&key));
|
2013-01-14 09:27:26 -06:00
|
|
|
check_structure(&map);
|
2014-04-05 00:45:42 -05:00
|
|
|
check_equal(ctrl.as_slice(), &map);
|
2014-01-29 18:20:34 -06:00
|
|
|
}
|
|
|
|
}
|
2012-01-17 21:05:07 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-01-14 09:27:26 -06:00
|
|
|
fn test_len() {
|
|
|
|
let mut m = TreeMap::new();
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(m.insert(3i, 6i));
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(m.len(), 1);
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(m.insert(0, 0));
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(m.len(), 2);
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(m.insert(4, 8));
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(m.len(), 3);
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(m.remove(&3));
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(m.len(), 2);
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(!m.remove(&5));
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(m.len(), 2);
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(m.insert(2, 4));
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(m.len(), 3);
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(m.insert(1, 2));
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(m.len(), 4);
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-06-26 06:49:06 -05:00
|
|
|
fn test_iterator() {
|
2013-01-14 09:27:26 -06:00
|
|
|
let mut m = TreeMap::new();
|
|
|
|
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(m.insert(3i, 6i));
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(m.insert(0, 0));
|
|
|
|
assert!(m.insert(4, 8));
|
|
|
|
assert!(m.insert(2, 4));
|
|
|
|
assert!(m.insert(1, 2));
|
2013-01-14 09:27:26 -06:00
|
|
|
|
|
|
|
let mut n = 0;
|
2013-08-03 11:45:23 -05:00
|
|
|
for (k, v) in m.iter() {
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(*k, n);
|
|
|
|
assert_eq!(*v, n * 2);
|
2013-01-14 09:27:26 -06:00
|
|
|
n += 1;
|
|
|
|
}
|
2013-07-31 11:24:35 -05:00
|
|
|
assert_eq!(n, 5);
|
2012-01-17 21:05:07 -06:00
|
|
|
}
|
|
|
|
|
2013-08-01 15:59:07 -05:00
|
|
|
#[test]
|
|
|
|
fn test_interval_iteration() {
|
|
|
|
let mut m = TreeMap::new();
|
2014-04-21 16:58:52 -05:00
|
|
|
for i in range(1i, 100i) {
|
2013-08-01 15:59:07 -05:00
|
|
|
assert!(m.insert(i * 2, i * 4));
|
|
|
|
}
|
|
|
|
|
2014-04-21 16:58:52 -05:00
|
|
|
for i in range(1i, 198i) {
|
2013-11-23 04:18:51 -06:00
|
|
|
let mut lb_it = m.lower_bound(&i);
|
2013-08-01 15:59:07 -05:00
|
|
|
let (&k, &v) = lb_it.next().unwrap();
|
|
|
|
let lb = i + i % 2;
|
|
|
|
assert_eq!(lb, k);
|
|
|
|
assert_eq!(lb * 2, v);
|
|
|
|
|
2013-11-23 04:18:51 -06:00
|
|
|
let mut ub_it = m.upper_bound(&i);
|
2013-08-01 15:59:07 -05:00
|
|
|
let (&k, &v) = ub_it.next().unwrap();
|
|
|
|
let ub = i + 2 - i % 2;
|
|
|
|
assert_eq!(ub, k);
|
|
|
|
assert_eq!(ub * 2, v);
|
|
|
|
}
|
2013-11-23 04:18:51 -06:00
|
|
|
let mut end_it = m.lower_bound(&199);
|
2013-08-01 15:59:07 -05:00
|
|
|
assert_eq!(end_it.next(), None);
|
|
|
|
}
|
|
|
|
|
2012-01-17 21:05:07 -06:00
|
|
|
#[test]
|
2013-08-06 15:53:51 -05:00
|
|
|
fn test_rev_iter() {
|
2013-01-14 09:27:26 -06:00
|
|
|
let mut m = TreeMap::new();
|
|
|
|
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(m.insert(3i, 6i));
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(m.insert(0, 0));
|
|
|
|
assert!(m.insert(4, 8));
|
|
|
|
assert!(m.insert(2, 4));
|
|
|
|
assert!(m.insert(1, 2));
|
2012-01-17 21:05:07 -06:00
|
|
|
|
2013-01-14 09:27:26 -06:00
|
|
|
let mut n = 4;
|
2013-08-06 15:53:51 -05:00
|
|
|
for (k, v) in m.rev_iter() {
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(*k, n);
|
|
|
|
assert_eq!(*v, n * 2);
|
2013-01-14 09:27:26 -06:00
|
|
|
n -= 1;
|
2013-08-06 15:53:51 -05:00
|
|
|
}
|
2012-01-17 21:05:07 -06:00
|
|
|
}
|
|
|
|
|
2014-01-05 07:40:53 -06:00
|
|
|
#[test]
|
|
|
|
fn test_mut_iter() {
|
|
|
|
let mut m = TreeMap::new();
|
|
|
|
for i in range(0u, 10) {
|
|
|
|
assert!(m.insert(i, 100 * i));
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i, (&k, v)) in m.mut_iter().enumerate() {
|
|
|
|
*v += k * 10 + i; // 000 + 00 + 0, 100 + 10 + 1, ...
|
|
|
|
}
|
|
|
|
|
|
|
|
for (&k, &v) in m.iter() {
|
|
|
|
assert_eq!(v, 111 * k);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#[test]
|
|
|
|
fn test_mut_rev_iter() {
|
|
|
|
let mut m = TreeMap::new();
|
|
|
|
for i in range(0u, 10) {
|
|
|
|
assert!(m.insert(i, 100 * i));
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i, (&k, v)) in m.mut_rev_iter().enumerate() {
|
|
|
|
*v += k * 10 + (9 - i); // 900 + 90 + (9 - 0), 800 + 80 + (9 - 1), ...
|
|
|
|
}
|
|
|
|
|
|
|
|
for (&k, &v) in m.iter() {
|
|
|
|
assert_eq!(v, 111 * k);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_mut_interval_iter() {
|
|
|
|
let mut m_lower = TreeMap::new();
|
|
|
|
let mut m_upper = TreeMap::new();
|
2014-04-21 16:58:52 -05:00
|
|
|
for i in range(1i, 100i) {
|
2014-01-05 07:40:53 -06:00
|
|
|
assert!(m_lower.insert(i * 2, i * 4));
|
|
|
|
assert!(m_upper.insert(i * 2, i * 4));
|
|
|
|
}
|
|
|
|
|
2014-04-21 16:58:52 -05:00
|
|
|
for i in range(1i, 199) {
|
2014-01-05 07:40:53 -06:00
|
|
|
let mut lb_it = m_lower.mut_lower_bound(&i);
|
|
|
|
let (&k, v) = lb_it.next().unwrap();
|
|
|
|
let lb = i + i % 2;
|
|
|
|
assert_eq!(lb, k);
|
|
|
|
*v -= k;
|
|
|
|
}
|
2014-04-21 16:58:52 -05:00
|
|
|
for i in range(0i, 198) {
|
2014-01-05 07:40:53 -06:00
|
|
|
let mut ub_it = m_upper.mut_upper_bound(&i);
|
|
|
|
let (&k, v) = ub_it.next().unwrap();
|
|
|
|
let ub = i + 2 - i % 2;
|
|
|
|
assert_eq!(ub, k);
|
|
|
|
*v -= k;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert!(m_lower.mut_lower_bound(&199).next().is_none());
|
|
|
|
|
|
|
|
assert!(m_upper.mut_upper_bound(&198).next().is_none());
|
|
|
|
|
|
|
|
assert!(m_lower.iter().all(|(_, &x)| x == 0));
|
|
|
|
assert!(m_upper.iter().all(|(_, &x)| x == 0));
|
|
|
|
}
|
|
|
|
|
2012-10-04 17:18:02 -05:00
|
|
|
#[test]
|
2013-01-14 09:27:26 -06:00
|
|
|
fn test_eq() {
|
|
|
|
let mut a = TreeMap::new();
|
|
|
|
let mut b = TreeMap::new();
|
2012-10-04 17:18:02 -05:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(a == b);
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(a.insert(0i, 5i));
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(a != b);
|
|
|
|
assert!(b.insert(0, 4));
|
|
|
|
assert!(a != b);
|
|
|
|
assert!(a.insert(5, 19));
|
|
|
|
assert!(a != b);
|
|
|
|
assert!(!b.insert(0, 5));
|
|
|
|
assert!(a != b);
|
|
|
|
assert!(b.insert(5, 19));
|
|
|
|
assert!(a == b);
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
2013-01-26 11:40:41 -06:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_lt() {
|
|
|
|
let mut a = TreeMap::new();
|
|
|
|
let mut b = TreeMap::new();
|
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(!(a < b) && !(b < a));
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(b.insert(0i, 5i));
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(a < b);
|
|
|
|
assert!(a.insert(0, 7));
|
2013-07-01 10:51:34 -05:00
|
|
|
assert!(!(a < b) && b < a);
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(b.insert(-2, 0));
|
|
|
|
assert!(b < a);
|
|
|
|
assert!(a.insert(-5, 2));
|
|
|
|
assert!(a < b);
|
|
|
|
assert!(a.insert(6, 2));
|
|
|
|
assert!(a < b && !(b < a));
|
2013-01-26 11:40:41 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_ord() {
|
|
|
|
let mut a = TreeMap::new();
|
|
|
|
let mut b = TreeMap::new();
|
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(a <= b && a >= b);
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(a.insert(1i, 1i));
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(a > b && a >= b);
|
|
|
|
assert!(b < a && b <= a);
|
|
|
|
assert!(b.insert(2, 2));
|
|
|
|
assert!(b > a && b >= a);
|
|
|
|
assert!(a < b && a <= b);
|
2013-01-26 11:40:41 -06:00
|
|
|
}
|
2013-01-14 19:41:11 -06:00
|
|
|
|
2014-05-27 12:38:52 -05:00
|
|
|
#[test]
|
|
|
|
fn test_show() {
|
|
|
|
let mut map: TreeMap<int, int> = TreeMap::new();
|
|
|
|
let empty: TreeMap<int, int> = TreeMap::new();
|
|
|
|
|
|
|
|
map.insert(1, 2);
|
|
|
|
map.insert(3, 4);
|
|
|
|
|
|
|
|
let map_str = format!("{}", map);
|
|
|
|
|
2014-05-29 13:59:53 -05:00
|
|
|
assert!(map_str == "{1: 2, 3: 4}".to_string());
|
|
|
|
assert_eq!(format!("{}", empty), "{}".to_string());
|
2014-05-27 12:38:52 -05:00
|
|
|
}
|
|
|
|
|
2013-01-14 19:41:11 -06:00
|
|
|
#[test]
|
|
|
|
fn test_lazy_iterator() {
|
|
|
|
let mut m = TreeMap::new();
|
2014-04-21 16:58:52 -05:00
|
|
|
let (x1, y1) = (2i, 5i);
|
2013-01-14 19:41:11 -06:00
|
|
|
let (x2, y2) = (9, 12);
|
|
|
|
let (x3, y3) = (20, -3);
|
|
|
|
let (x4, y4) = (29, 5);
|
|
|
|
let (x5, y5) = (103, 3);
|
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(m.insert(x1, y1));
|
|
|
|
assert!(m.insert(x2, y2));
|
|
|
|
assert!(m.insert(x3, y3));
|
|
|
|
assert!(m.insert(x4, y4));
|
|
|
|
assert!(m.insert(x5, y5));
|
2013-01-14 19:41:11 -06:00
|
|
|
|
|
|
|
let m = m;
|
2013-02-26 13:15:08 -06:00
|
|
|
let mut a = m.iter();
|
2013-01-14 19:41:11 -06:00
|
|
|
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.next().unwrap(), (&x1, &y1));
|
|
|
|
assert_eq!(a.next().unwrap(), (&x2, &y2));
|
|
|
|
assert_eq!(a.next().unwrap(), (&x3, &y3));
|
|
|
|
assert_eq!(a.next().unwrap(), (&x4, &y4));
|
|
|
|
assert_eq!(a.next().unwrap(), (&x5, &y5));
|
2013-02-26 13:15:08 -06:00
|
|
|
|
2013-04-09 09:54:32 -05:00
|
|
|
assert!(a.next().is_none());
|
2013-02-26 13:15:08 -06:00
|
|
|
|
|
|
|
let mut b = m.iter();
|
|
|
|
|
|
|
|
let expected = [(&x1, &y1), (&x2, &y2), (&x3, &y3), (&x4, &y4),
|
|
|
|
(&x5, &y5)];
|
|
|
|
let mut i = 0;
|
|
|
|
|
2013-08-03 11:45:23 -05:00
|
|
|
for x in b {
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(expected[i], x);
|
2013-02-26 13:15:08 -06:00
|
|
|
i += 1;
|
|
|
|
|
|
|
|
if i == 2 {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-03 11:45:23 -05:00
|
|
|
for x in b {
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(expected[i], x);
|
2013-02-26 13:15:08 -06:00
|
|
|
i += 1;
|
|
|
|
}
|
2013-01-14 19:41:11 -06:00
|
|
|
}
|
2013-07-14 12:18:50 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from_iter() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let xs = [(1i, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
|
2013-07-14 12:18:50 -05:00
|
|
|
|
2013-08-09 22:09:47 -05:00
|
|
|
let map: TreeMap<int, int> = xs.iter().map(|&x| x).collect();
|
2013-07-14 12:18:50 -05:00
|
|
|
|
2013-08-03 11:45:23 -05:00
|
|
|
for &(k, v) in xs.iter() {
|
2013-07-14 12:18:50 -05:00
|
|
|
assert_eq!(map.find(&k), Some(&v));
|
|
|
|
}
|
|
|
|
}
|
2013-07-19 16:07:00 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod bench {
|
2014-05-29 21:03:06 -05:00
|
|
|
use test::Bencher;
|
|
|
|
|
2014-02-02 23:56:49 -06:00
|
|
|
use super::TreeMap;
|
|
|
|
use deque::bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
|
2013-07-19 16:07:00 -05:00
|
|
|
|
|
|
|
// Find seq
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
pub fn insert_rand_100(b: &mut Bencher) {
|
2013-07-19 16:07:00 -05:00
|
|
|
let mut m : TreeMap<uint,uint> = TreeMap::new();
|
2014-03-31 20:16:35 -05:00
|
|
|
insert_rand_n(100, &mut m, b);
|
2013-07-19 16:07:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
pub fn insert_rand_10_000(b: &mut Bencher) {
|
2013-07-19 16:07:00 -05:00
|
|
|
let mut m : TreeMap<uint,uint> = TreeMap::new();
|
2014-03-31 20:16:35 -05:00
|
|
|
insert_rand_n(10_000, &mut m, b);
|
2013-07-19 16:07:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Insert seq
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
pub fn insert_seq_100(b: &mut Bencher) {
|
2013-07-19 16:07:00 -05:00
|
|
|
let mut m : TreeMap<uint,uint> = TreeMap::new();
|
2014-03-31 20:16:35 -05:00
|
|
|
insert_seq_n(100, &mut m, b);
|
2013-07-19 16:07:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
pub fn insert_seq_10_000(b: &mut Bencher) {
|
2013-07-19 16:07:00 -05:00
|
|
|
let mut m : TreeMap<uint,uint> = TreeMap::new();
|
2014-03-31 20:16:35 -05:00
|
|
|
insert_seq_n(10_000, &mut m, b);
|
2013-07-19 16:07:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Find rand
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
pub fn find_rand_100(b: &mut Bencher) {
|
2013-07-19 16:07:00 -05:00
|
|
|
let mut m : TreeMap<uint,uint> = TreeMap::new();
|
2014-03-31 20:16:35 -05:00
|
|
|
find_rand_n(100, &mut m, b);
|
2013-07-19 16:07:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
pub fn find_rand_10_000(b: &mut Bencher) {
|
2013-07-19 16:07:00 -05:00
|
|
|
let mut m : TreeMap<uint,uint> = TreeMap::new();
|
2014-03-31 20:16:35 -05:00
|
|
|
find_rand_n(10_000, &mut m, b);
|
2013-07-19 16:07:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Find seq
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
pub fn find_seq_100(b: &mut Bencher) {
|
2013-07-19 16:07:00 -05:00
|
|
|
let mut m : TreeMap<uint,uint> = TreeMap::new();
|
2014-03-31 20:16:35 -05:00
|
|
|
find_seq_n(100, &mut m, b);
|
2013-07-19 16:07:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
pub fn find_seq_10_000(b: &mut Bencher) {
|
2013-07-19 16:07:00 -05:00
|
|
|
let mut m : TreeMap<uint,uint> = TreeMap::new();
|
2014-03-31 20:16:35 -05:00
|
|
|
find_seq_n(10_000, &mut m, b);
|
2013-07-19 16:07:00 -05:00
|
|
|
}
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
2012-10-04 17:18:02 -05:00
|
|
|
|
2013-01-14 09:27:26 -06:00
|
|
|
#[cfg(test)]
|
|
|
|
mod test_set {
|
2014-05-29 21:03:06 -05:00
|
|
|
use std::prelude::*;
|
2014-07-12 12:23:20 -05:00
|
|
|
use std::hash;
|
2013-05-24 21:35:29 -05:00
|
|
|
|
2014-06-06 18:33:44 -05:00
|
|
|
use {Set, MutableSet, Mutable, MutableMap};
|
2014-02-02 23:56:49 -06:00
|
|
|
use super::{TreeMap, TreeSet};
|
2012-10-04 17:18:02 -05:00
|
|
|
|
2013-01-21 16:25:57 -06:00
|
|
|
#[test]
|
|
|
|
fn test_clear() {
|
|
|
|
let mut s = TreeSet::new();
|
|
|
|
s.clear();
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(s.insert(5i));
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(s.insert(12));
|
|
|
|
assert!(s.insert(19));
|
2013-01-21 16:25:57 -06:00
|
|
|
s.clear();
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(!s.contains(&5));
|
|
|
|
assert!(!s.contains(&12));
|
|
|
|
assert!(!s.contains(&19));
|
|
|
|
assert!(s.is_empty());
|
2013-01-21 16:25:57 -06:00
|
|
|
}
|
|
|
|
|
2013-01-14 09:27:26 -06:00
|
|
|
#[test]
|
|
|
|
fn test_disjoint() {
|
|
|
|
let mut xs = TreeSet::new();
|
|
|
|
let mut ys = TreeSet::new();
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(xs.is_disjoint(&ys));
|
|
|
|
assert!(ys.is_disjoint(&xs));
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(xs.insert(5i));
|
|
|
|
assert!(ys.insert(11i));
|
2013-03-28 20:39:09 -05:00
|
|
|
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!(ys.insert(-11));
|
|
|
|
assert!(xs.is_disjoint(&ys));
|
|
|
|
assert!(ys.is_disjoint(&xs));
|
|
|
|
assert!(ys.insert(7));
|
|
|
|
assert!(!xs.is_disjoint(&ys));
|
|
|
|
assert!(!ys.is_disjoint(&xs));
|
2012-10-04 17:18:02 -05:00
|
|
|
}
|
|
|
|
|
2012-01-17 21:05:07 -06:00
|
|
|
#[test]
|
2013-01-14 09:27:26 -06:00
|
|
|
fn test_subset_and_superset() {
|
|
|
|
let mut a = TreeSet::new();
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(a.insert(0i));
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(a.insert(5));
|
|
|
|
assert!(a.insert(11));
|
|
|
|
assert!(a.insert(7));
|
2012-01-17 21:05:07 -06:00
|
|
|
|
2013-01-14 09:27:26 -06:00
|
|
|
let mut b = TreeSet::new();
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(b.insert(0i));
|
2013-03-28 20:39:09 -05:00
|
|
|
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));
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-06-26 06:49:06 -05:00
|
|
|
fn test_iterator() {
|
2013-01-14 09:27:26 -06:00
|
|
|
let mut m = TreeSet::new();
|
|
|
|
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(m.insert(3i));
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(m.insert(0));
|
|
|
|
assert!(m.insert(4));
|
|
|
|
assert!(m.insert(2));
|
|
|
|
assert!(m.insert(1));
|
2013-01-14 09:27:26 -06:00
|
|
|
|
|
|
|
let mut n = 0;
|
2013-08-03 11:45:23 -05:00
|
|
|
for x in m.iter() {
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(*x, n);
|
2013-01-14 09:27:26 -06:00
|
|
|
n += 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-08-06 15:53:51 -05:00
|
|
|
fn test_rev_iter() {
|
2013-01-14 09:27:26 -06:00
|
|
|
let mut m = TreeSet::new();
|
|
|
|
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(m.insert(3i));
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(m.insert(0));
|
|
|
|
assert!(m.insert(4));
|
|
|
|
assert!(m.insert(2));
|
|
|
|
assert!(m.insert(1));
|
2013-01-14 09:27:26 -06:00
|
|
|
|
|
|
|
let mut n = 4;
|
2013-08-06 15:53:51 -05:00
|
|
|
for x in m.rev_iter() {
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(*x, n);
|
2013-07-31 14:07:44 -05:00
|
|
|
n -= 1;
|
2013-08-06 15:53:51 -05:00
|
|
|
}
|
2013-01-14 09:27:26 -06:00
|
|
|
}
|
|
|
|
|
2014-05-11 21:34:44 -05:00
|
|
|
#[test]
|
|
|
|
fn test_move_iter() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let s: TreeSet<int> = range(0i, 5).collect();
|
2014-05-11 21:34:44 -05:00
|
|
|
|
|
|
|
let mut n = 0;
|
|
|
|
for x in s.move_iter() {
|
|
|
|
assert_eq!(x, n);
|
|
|
|
n += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_move_iter_size_hint() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let s: TreeSet<int> = vec!(0i, 1).move_iter().collect();
|
2014-05-11 21:34:44 -05:00
|
|
|
|
|
|
|
let mut it = s.move_iter();
|
|
|
|
|
|
|
|
assert_eq!(it.size_hint(), (2, Some(2)));
|
|
|
|
assert!(it.next() != None);
|
|
|
|
|
|
|
|
assert_eq!(it.size_hint(), (1, Some(1)));
|
|
|
|
assert!(it.next() != None);
|
|
|
|
|
|
|
|
assert_eq!(it.size_hint(), (0, Some(0)));
|
|
|
|
assert_eq!(it.next(), None);
|
|
|
|
}
|
|
|
|
|
2014-01-13 02:25:30 -06:00
|
|
|
#[test]
|
|
|
|
fn test_clone_eq() {
|
|
|
|
let mut m = TreeSet::new();
|
|
|
|
|
2014-04-21 16:58:52 -05:00
|
|
|
m.insert(1i);
|
2014-01-13 02:25:30 -06:00
|
|
|
m.insert(2);
|
|
|
|
|
|
|
|
assert!(m.clone() == m);
|
|
|
|
}
|
|
|
|
|
2014-07-12 12:23:20 -05:00
|
|
|
#[test]
|
|
|
|
fn test_hash() {
|
|
|
|
let mut x = TreeSet::new();
|
|
|
|
let mut y = TreeSet::new();
|
|
|
|
|
|
|
|
x.insert(1i);
|
|
|
|
x.insert(2);
|
|
|
|
x.insert(3);
|
|
|
|
|
|
|
|
y.insert(3i);
|
|
|
|
y.insert(2);
|
|
|
|
y.insert(1);
|
|
|
|
|
|
|
|
assert!(hash::hash(&x) == hash::hash(&y));
|
|
|
|
}
|
|
|
|
|
2013-11-18 23:54:13 -06:00
|
|
|
fn check(a: &[int],
|
|
|
|
b: &[int],
|
|
|
|
expected: &[int],
|
|
|
|
f: |&TreeSet<int>, &TreeSet<int>, f: |&int| -> bool| -> bool) {
|
2013-03-10 19:38:12 -05:00
|
|
|
let mut set_a = TreeSet::new();
|
|
|
|
let mut set_b = TreeSet::new();
|
2013-01-14 09:27:26 -06:00
|
|
|
|
2013-08-03 11:45:23 -05:00
|
|
|
for x in a.iter() { assert!(set_a.insert(*x)) }
|
|
|
|
for y in b.iter() { assert!(set_b.insert(*y)) }
|
2013-01-14 09:27:26 -06:00
|
|
|
|
|
|
|
let mut i = 0;
|
2013-11-21 21:20:48 -06:00
|
|
|
f(&set_a, &set_b, |x| {
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(*x, expected[i]);
|
2013-03-10 19:38:12 -05:00
|
|
|
i += 1;
|
2013-07-31 14:07:44 -05:00
|
|
|
true
|
2013-11-21 21:20:48 -06:00
|
|
|
});
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(i, expected.len());
|
2012-01-17 21:05:07 -06:00
|
|
|
}
|
2013-01-15 07:55:13 -06:00
|
|
|
|
|
|
|
#[test]
|
2013-03-10 19:38:12 -05:00
|
|
|
fn test_intersection() {
|
|
|
|
fn check_intersection(a: &[int], b: &[int], expected: &[int]) {
|
2014-06-12 04:19:55 -05:00
|
|
|
check(a, b, expected, |x, y, f| x.intersection(y).all(f))
|
2013-03-10 19:38:12 -05:00
|
|
|
}
|
2013-01-15 07:55:13 -06:00
|
|
|
|
2013-03-10 19:41:50 -05:00
|
|
|
check_intersection([], [], []);
|
|
|
|
check_intersection([1, 2, 3], [], []);
|
|
|
|
check_intersection([], [1, 2, 3], []);
|
|
|
|
check_intersection([2], [1, 2, 3], [2]);
|
|
|
|
check_intersection([1, 2, 3], [2], [2]);
|
2013-03-10 19:38:12 -05:00
|
|
|
check_intersection([11, 1, 3, 77, 103, 5, -5],
|
|
|
|
[2, 11, 77, -9, -42, 5, 3],
|
|
|
|
[3, 5, 11, 77]);
|
|
|
|
}
|
2013-01-15 07:55:13 -06:00
|
|
|
|
2013-03-10 19:38:12 -05:00
|
|
|
#[test]
|
|
|
|
fn test_difference() {
|
|
|
|
fn check_difference(a: &[int], b: &[int], expected: &[int]) {
|
2014-06-12 04:19:55 -05:00
|
|
|
check(a, b, expected, |x, y, f| x.difference(y).all(f))
|
2013-01-15 09:21:45 -06:00
|
|
|
}
|
2013-03-10 19:25:09 -05:00
|
|
|
|
|
|
|
check_difference([], [], []);
|
|
|
|
check_difference([1, 12], [], [1, 12]);
|
|
|
|
check_difference([], [1, 2, 3, 9], []);
|
|
|
|
check_difference([1, 3, 5, 9, 11],
|
|
|
|
[3, 9],
|
|
|
|
[1, 5, 11]);
|
|
|
|
check_difference([-5, 11, 22, 33, 40, 42],
|
|
|
|
[-12, -5, 14, 23, 34, 38, 39, 50],
|
|
|
|
[11, 22, 33, 40, 42]);
|
2013-01-15 09:21:45 -06:00
|
|
|
}
|
|
|
|
|
2013-01-15 10:41:47 -06:00
|
|
|
#[test]
|
|
|
|
fn test_symmetric_difference() {
|
2013-03-10 19:38:12 -05:00
|
|
|
fn check_symmetric_difference(a: &[int], b: &[int],
|
|
|
|
expected: &[int]) {
|
2014-06-12 04:19:55 -05:00
|
|
|
check(a, b, expected, |x, y, f| x.symmetric_difference(y).all(f))
|
2013-01-15 10:41:47 -06:00
|
|
|
}
|
2013-03-10 19:38:12 -05:00
|
|
|
|
2013-03-10 19:41:50 -05:00
|
|
|
check_symmetric_difference([], [], []);
|
|
|
|
check_symmetric_difference([1, 2, 3], [2], [1, 3]);
|
|
|
|
check_symmetric_difference([2], [1, 2, 3], [1, 3]);
|
2013-03-10 19:38:12 -05:00
|
|
|
check_symmetric_difference([1, 3, 5, 9, 11],
|
|
|
|
[-2, 3, 9, 14, 22],
|
|
|
|
[-2, 1, 5, 11, 14, 22]);
|
2013-01-15 10:41:47 -06:00
|
|
|
}
|
|
|
|
|
2013-01-15 09:21:45 -06:00
|
|
|
#[test]
|
|
|
|
fn test_union() {
|
2013-03-10 19:38:12 -05:00
|
|
|
fn check_union(a: &[int], b: &[int],
|
|
|
|
expected: &[int]) {
|
2014-06-12 04:19:55 -05:00
|
|
|
check(a, b, expected, |x, y, f| x.union(y).all(f))
|
2013-01-15 07:55:13 -06:00
|
|
|
}
|
2013-03-10 19:38:12 -05:00
|
|
|
|
2013-03-10 19:41:50 -05:00
|
|
|
check_union([], [], []);
|
|
|
|
check_union([1, 2, 3], [2], [1, 2, 3]);
|
2013-03-10 19:44:18 -05:00
|
|
|
check_union([2], [1, 2, 3], [1, 2, 3]);
|
2013-03-10 19:38:12 -05:00
|
|
|
check_union([1, 3, 5, 9, 11, 16, 19, 24],
|
|
|
|
[-2, 1, 5, 9, 13, 19],
|
|
|
|
[-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]);
|
2013-01-15 07:55:13 -06:00
|
|
|
}
|
2013-04-09 09:54:32 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_zip() {
|
|
|
|
let mut x = TreeSet::new();
|
|
|
|
x.insert(5u);
|
|
|
|
x.insert(12u);
|
|
|
|
x.insert(11u);
|
|
|
|
|
|
|
|
let mut y = TreeSet::new();
|
|
|
|
y.insert("foo");
|
|
|
|
y.insert("bar");
|
|
|
|
|
|
|
|
let x = x;
|
|
|
|
let y = y;
|
2013-04-15 09:30:16 -05:00
|
|
|
let mut z = x.iter().zip(y.iter());
|
2013-04-09 09:54:32 -05:00
|
|
|
|
|
|
|
// FIXME: #5801: this needs a type hint to compile...
|
|
|
|
let result: Option<(&uint, & &'static str)> = z.next();
|
2014-05-01 00:32:13 -05:00
|
|
|
assert_eq!(result.unwrap(), (&5u, &("bar")));
|
2013-04-09 09:54:32 -05:00
|
|
|
|
|
|
|
let result: Option<(&uint, & &'static str)> = z.next();
|
2014-05-01 00:32:13 -05:00
|
|
|
assert_eq!(result.unwrap(), (&11u, &("foo")));
|
2013-04-09 09:54:32 -05:00
|
|
|
|
|
|
|
let result: Option<(&uint, & &'static str)> = z.next();
|
|
|
|
assert!(result.is_none());
|
|
|
|
}
|
2013-05-04 08:54:58 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_swap() {
|
|
|
|
let mut m = TreeMap::new();
|
2014-04-21 16:58:52 -05:00
|
|
|
assert_eq!(m.swap(1u, 2i), None);
|
|
|
|
assert_eq!(m.swap(1u, 3i), Some(2));
|
|
|
|
assert_eq!(m.swap(1u, 4i), Some(3));
|
2013-05-04 08:54:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_pop() {
|
|
|
|
let mut m = TreeMap::new();
|
2014-04-21 16:58:52 -05:00
|
|
|
m.insert(1u, 2i);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(m.pop(&1), Some(2));
|
|
|
|
assert_eq!(m.pop(&1), None);
|
2013-05-04 08:54:58 -05:00
|
|
|
}
|
2013-07-14 12:18:50 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from_iter() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let xs = [1i, 2, 3, 4, 5, 6, 7, 8, 9];
|
2013-07-14 12:18:50 -05:00
|
|
|
|
2013-08-09 22:09:47 -05:00
|
|
|
let set: TreeSet<int> = xs.iter().map(|&x| x).collect();
|
2013-07-14 12:18:50 -05:00
|
|
|
|
2013-08-03 11:45:23 -05:00
|
|
|
for x in xs.iter() {
|
2013-07-14 12:18:50 -05:00
|
|
|
assert!(set.contains(x));
|
|
|
|
}
|
|
|
|
}
|
2014-05-27 12:38:52 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_show() {
|
|
|
|
let mut set: TreeSet<int> = TreeSet::new();
|
|
|
|
let empty: TreeSet<int> = TreeSet::new();
|
|
|
|
|
|
|
|
set.insert(1);
|
|
|
|
set.insert(2);
|
|
|
|
|
|
|
|
let set_str = format!("{}", set);
|
|
|
|
|
2014-05-29 13:59:53 -05:00
|
|
|
assert!(set_str == "{1, 2}".to_string());
|
|
|
|
assert_eq!(format!("{}", empty), "{}".to_string());
|
2014-05-27 12:38:52 -05:00
|
|
|
}
|
2012-05-23 19:18:31 -05:00
|
|
|
}
|