about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-03-15 22:39:42 -0700
committerbors <bors@rust-lang.org>2013-03-15 22:39:42 -0700
commitebba8b4e3591c95508a4c1121784e768272a574a (patch)
treec03376d29dbe1548524c430938a820ec9cbfac72
parentdc5ad5070d06015d6a45f656882ae245197d0ff8 (diff)
parentd856215b925441a4889cb23cab5758c36e4a4746 (diff)
downloadrust-ebba8b4e3591c95508a4c1121784e768272a574a.tar.gz
rust-ebba8b4e3591c95508a4c1121784e768272a574a.zip
auto merge of #5408 : thestinger/rust/trie, r=pcwalton
The chunk fix is cherry picked from @graydon's `gc` branch.
-rw-r--r--src/libcore/trie.rs33
1 files changed, 31 insertions, 2 deletions
diff --git a/src/libcore/trie.rs b/src/libcore/trie.rs
index 966db4ec662..15b0e160434 100644
--- a/src/libcore/trie.rs
+++ b/src/libcore/trie.rs
@@ -137,6 +137,7 @@ impl<T> Map<uint, T> for TrieMap<T> {
 }
 
 impl<T> TrieMap<T> {
+    /// Create an empty TrieMap
     #[inline(always)]
     static pure fn new() -> TrieMap<T> {
         TrieMap{root: TrieNode::new(), length: 0}
@@ -191,6 +192,12 @@ impl Mutable for TrieSet {
 }
 
 impl TrieSet {
+    /// Create an empty TrieSet
+    #[inline(always)]
+    static pure fn new() -> TrieSet {
+        TrieSet{map: TrieMap::new()}
+    }
+
     /// Return true if the set contains a value
     #[inline(always)]
     pure fn contains(&self, value: &uint) -> bool {
@@ -265,8 +272,8 @@ impl<T> TrieNode<T> {
 // if this was done via a trait, the key could be generic
 #[inline(always)]
 pure fn chunk(n: uint, idx: uint) -> uint {
-    let real_idx = uint::bytes - 1 - idx;
-    (n >> (SHIFT * real_idx)) & MASK
+    let sh = uint::bits - (SHIFT * (idx + 1));
+    (n >> sh) & MASK
 }
 
 fn insert<T>(count: &mut uint, child: &mut Child<T>, key: uint, value: T,
@@ -462,4 +469,26 @@ mod tests {
             n -= 1;
         }
     }
+
+    #[test]
+    fn test_sane_chunk() {
+        let x = 1;
+        let y = 1 << (uint::bits - 1);
+
+        let mut trie = TrieSet::new();
+
+        fail_unless!(trie.insert(x));
+        fail_unless!(trie.insert(y));
+
+        fail_unless!(trie.len() == 2);
+
+        let expected = [x, y];
+
+        let mut i = 0;
+
+        for trie.each |x| {
+            fail_unless!(expected[i] == *x);
+            i += 1;
+        }
+    }
 }