Skip to content

Commit

Permalink
Document TrieSet and TrieMap methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
treeman authored and alexcrichton committed Jul 24, 2014
1 parent 237738f commit a524928
Showing 1 changed file with 191 additions and 16 deletions.
207 changes: 191 additions & 16 deletions src/libcollections/trie.rs
Expand Up @@ -8,7 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Ordered containers with integer keys, implemented as radix tries (`TrieSet` and `TrieMap` types)
//! Ordered containers with unsigned integer keys,
//! implemented as radix tries (`TrieSet` and `TrieMap` types).

use core::prelude::*;

Expand All @@ -35,7 +36,7 @@ enum Child<T> {
Nothing
}

#[allow(missing_doc)]
/// A map as a radix trie.
pub struct TrieMap<T> {
root: TrieNode<T>,
length: uint
Expand All @@ -51,7 +52,7 @@ impl<T: PartialEq> PartialEq for TrieMap<T> {
impl<T: Eq> Eq for TrieMap<T> {}

impl<T> Collection for TrieMap<T> {
/// Return the number of elements in the map
/// Return the number of elements in the map.
#[inline]
fn len(&self) -> uint { self.length }
}
Expand All @@ -66,7 +67,7 @@ impl<T> Mutable for TrieMap<T> {
}

impl<T> Map<uint, T> for TrieMap<T> {
/// Return a reference to the value corresponding to the key
/// Return a reference to the value corresponding to the key.
#[inline]
fn find<'a>(&'a self, key: &uint) -> Option<&'a T> {
let mut node: &'a TrieNode<T> = &self.root;
Expand All @@ -89,7 +90,7 @@ impl<T> Map<uint, T> for TrieMap<T> {
}

impl<T> MutableMap<uint, T> for TrieMap<T> {
/// Return a mutable reference to the value corresponding to the key
/// Return a mutable reference to the value corresponding to the key.
#[inline]
fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> {
find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1)
Expand Down Expand Up @@ -122,19 +123,54 @@ impl<T> Default for TrieMap<T> {
}

impl<T> TrieMap<T> {
/// Create an empty TrieMap
/// Create an empty TrieMap.
///
/// # Example
///
/// ```
/// use std::collections::TrieMap;
/// let mut map: TrieMap<&str> = TrieMap::new();
/// ```
#[inline]
pub fn new() -> TrieMap<T> {
TrieMap{root: TrieNode::new(), length: 0}
}

/// Visit all key-value pairs in reverse order
/// Visit all key-value pairs in reverse order. Abort traversal when f returns false.
/// Return true if f returns true for all elements.
///
/// # Example
///
/// ```
/// use std::collections::TrieMap;
/// let map: TrieMap<&str> = [(1, "a"), (2, "b"), (3, "c")].iter().map(|&x| x).collect();
///
/// let mut vec = Vec::new();
/// assert_eq!(true, map.each_reverse(|&key, &value| { vec.push((key, value)); true }));
/// assert_eq!(vec, vec![(3, "c"), (2, "b"), (1, "a")]);
///
/// // Stop when we reach 2
/// let mut vec = Vec::new();
/// assert_eq!(false, map.each_reverse(|&key, &value| { vec.push(value); key != 2 }));
/// assert_eq!(vec, vec!["c", "b"]);
/// ```
#[inline]
pub fn each_reverse<'a>(&'a self, f: |&uint, &'a T| -> bool) -> bool {
self.root.each_reverse(f)
}

/// Get an iterator over the key-value pairs in the map
/// Get an iterator over the key-value pairs in the map, ordered by keys.
///
/// # Example
///
/// ```
/// use std::collections::TrieMap;
/// let map: TrieMap<&str> = [(3, "c"), (1, "a"), (2, "b")].iter().map(|&x| x).collect();
///
/// for (key, value) in map.iter() {
/// println!("{}: {}", key, value);
/// }
/// ```
pub fn iter<'a>(&'a self) -> Entries<'a, T> {
let mut iter = unsafe {Entries::new()};
iter.stack[0] = self.root.children.iter();
Expand All @@ -147,6 +183,21 @@ impl<T> TrieMap<T> {

/// Get an iterator over the key-value pairs in the map, with the
/// ability to mutate the values.
///
/// # Example
///
/// ```
/// use std::collections::TrieMap;
/// let mut map: TrieMap<int> = [(1, 2), (2, 4), (3, 6)].iter().map(|&x| x).collect();
///
/// for (key, value) in map.mut_iter() {
/// *value = -(key as int);
/// }
///
/// assert_eq!(map.find(&1), Some(&-1));
/// assert_eq!(map.find(&2), Some(&-2));
/// assert_eq!(map.find(&3), Some(&-3));
/// ```
pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, T> {
let mut iter = unsafe {MutEntries::new()};
iter.stack[0] = self.root.children.mut_iter();
Expand Down Expand Up @@ -255,12 +306,34 @@ impl<T> TrieMap<T> {

/// Get an iterator pointing to the first key-value pair whose key is not less than `key`.
/// If all keys in the map are less than `key` an empty iterator is returned.
///
/// # Example
///
/// ```
/// use std::collections::TrieMap;
/// let map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
///
/// assert_eq!(map.lower_bound(4).next(), Some((4, &"b")));
/// assert_eq!(map.lower_bound(5).next(), Some((6, &"c")));
/// assert_eq!(map.lower_bound(10).next(), None);
/// ```
pub fn lower_bound<'a>(&'a self, key: uint) -> Entries<'a, T> {
self.bound(key, false)
}

/// Get an iterator pointing to the first key-value pair whose key is greater than `key`.
/// If all keys in the map are not greater than `key` an empty iterator is returned.
///
/// # Example
///
/// ```
/// use std::collections::TrieMap;
/// let map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
///
/// assert_eq!(map.upper_bound(4).next(), Some((6, &"c")));
/// assert_eq!(map.upper_bound(5).next(), Some((6, &"c")));
/// assert_eq!(map.upper_bound(10).next(), None);
/// ```
pub fn upper_bound<'a>(&'a self, key: uint) -> Entries<'a, T> {
self.bound(key, true)
}
Expand All @@ -275,12 +348,50 @@ impl<T> TrieMap<T> {

/// Get an iterator pointing to the first key-value pair whose key is not less than `key`.
/// If all keys in the map are less than `key` an empty iterator is returned.
///
/// # Example
///
/// ```
/// use std::collections::TrieMap;
/// let mut map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
///
/// assert_eq!(map.mut_lower_bound(4).next(), Some((4, &mut "b")));
/// assert_eq!(map.mut_lower_bound(5).next(), Some((6, &mut "c")));
/// assert_eq!(map.mut_lower_bound(10).next(), None);
///
/// for (key, value) in map.mut_lower_bound(4) {
/// *value = "changed";
/// }
///
/// assert_eq!(map.find(&2), Some(&"a"));
/// assert_eq!(map.find(&4), Some(&"changed"));
/// assert_eq!(map.find(&6), Some(&"changed"));
/// ```
pub fn mut_lower_bound<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> {
self.mut_bound(key, false)
}

/// Get an iterator pointing to the first key-value pair whose key is greater than `key`.
/// If all keys in the map are not greater than `key` an empty iterator is returned.
///
/// # Example
///
/// ```
/// use std::collections::TrieMap;
/// let mut map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
///
/// assert_eq!(map.mut_upper_bound(4).next(), Some((6, &mut "c")));
/// assert_eq!(map.mut_upper_bound(5).next(), Some((6, &mut "c")));
/// assert_eq!(map.mut_upper_bound(10).next(), None);
///
/// for (key, value) in map.mut_upper_bound(4) {
/// *value = "changed";
/// }
///
/// assert_eq!(map.find(&2), Some(&"a"));
/// assert_eq!(map.find(&4), Some(&"b"));
/// assert_eq!(map.find(&6), Some(&"changed"));
/// ```
pub fn mut_upper_bound<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> {
self.mut_bound(key, true)
}
Expand Down Expand Up @@ -310,14 +421,14 @@ impl<S: Writer, T: Hash<S>> Hash<S> for TrieMap<T> {
}
}

#[allow(missing_doc)]
/// A set as a radix trie.
#[deriving(Hash, PartialEq, Eq)]
pub struct TrieSet {
map: TrieMap<()>
}

impl Collection for TrieSet {
/// Return the number of elements in the set
/// Return the number of elements in the set.
#[inline]
fn len(&self) -> uint { self.map.len() }
}
Expand Down Expand Up @@ -368,32 +479,96 @@ impl Default for TrieSet {
}

impl TrieSet {
/// Create an empty TrieSet
/// Create an empty TrieSet.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
/// let mut set = TrieSet::new();
/// ```
#[inline]
pub fn new() -> TrieSet {
TrieSet{map: TrieMap::new()}
}

/// Visit all values in reverse order
/// Visit all values in reverse order. Abort traversal when `f` returns false.
/// Return `true` if `f` returns `true` for all elements.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let set: TrieSet = [1, 2, 3, 4, 5].iter().map(|&x| x).collect();
///
/// let mut vec = Vec::new();
/// assert_eq!(true, set.each_reverse(|&x| { vec.push(x); true }));
/// assert_eq!(vec, vec![5, 4, 3, 2, 1]);
///
/// // Stop when we reach 3
/// let mut vec = Vec::new();
/// assert_eq!(false, set.each_reverse(|&x| { vec.push(x); x != 3 }));
/// assert_eq!(vec, vec![5, 4, 3]);
/// ```
#[inline]
pub fn each_reverse(&self, f: |&uint| -> bool) -> bool {
self.map.each_reverse(|k, _| f(k))
}

/// Get an iterator over the values in the set
/// Get an iterator over the values in the set, in sorted order.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let mut set = TrieSet::new();
/// set.insert(3);
/// set.insert(2);
/// set.insert(1);
/// set.insert(2);
///
/// // Print 1, 2, 3
/// for x in set.iter() {
/// println!("{}", x);
/// }
/// ```
#[inline]
pub fn iter<'a>(&'a self) -> SetItems<'a> {
SetItems{iter: self.map.iter()}
}

/// Get an iterator pointing to the first value that is not less than `val`.
/// If all values in the set are less than `val` an empty iterator is returned.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let set: TrieSet = [2, 4, 6, 8].iter().map(|&x| x).collect();
/// assert_eq!(set.lower_bound(4).next(), Some(4));
/// assert_eq!(set.lower_bound(5).next(), Some(6));
/// assert_eq!(set.lower_bound(10).next(), None);
/// ```
pub fn lower_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
SetItems{iter: self.map.lower_bound(val)}
}

/// Get an iterator pointing to the first value that key is greater than `val`.
/// If all values in the set are not greater than `val` an empty iterator is returned.
/// If all values in the set are less than or equal to `val` an empty iterator is returned.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let set: TrieSet = [2, 4, 6, 8].iter().map(|&x| x).collect();
/// assert_eq!(set.upper_bound(4).next(), Some(6));
/// assert_eq!(set.upper_bound(5).next(), Some(6));
/// assert_eq!(set.upper_bound(10).next(), None);
/// ```
pub fn upper_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
SetItems{iter: self.map.upper_bound(val)}
}
Expand Down Expand Up @@ -526,7 +701,7 @@ fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
return ret;
}

/// Forward iterator over a map
/// Forward iterator over a map.
pub struct Entries<'a, T> {
stack: [slice::Items<'a, Child<T>>, .. NUM_CHUNKS],
length: uint,
Expand Down Expand Up @@ -660,7 +835,7 @@ macro_rules! iterator_impl {
iterator_impl! { Entries, iter = iter, mutability = }
iterator_impl! { MutEntries, iter = mut_iter, mutability = mut }

/// Forward iterator over a set
/// Forward iterator over a set.
pub struct SetItems<'a> {
iter: Entries<'a, ()>
}
Expand Down

0 comments on commit a524928

Please sign in to comment.