Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 30 additions & 16 deletions src/libcore/trie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use prelude::*;

// FIXME: #3469: need to manually update TrieNode when SHIFT changes
// FIXME: #5244: need to manually update the TrieNode constructor
const SHIFT: uint = 4;
const SIZE: uint = 1 << SHIFT;
const MASK: uint = SIZE - 1;
Expand Down Expand Up @@ -56,7 +57,7 @@ impl<T> Container for TrieMap<T> {
pure fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<T: Copy> Mutable for TrieMap<T> {
impl<T> Mutable for TrieMap<T> {
/// Clear the map, removing all values.
#[inline(always)]
fn clear(&mut self) {
Expand All @@ -65,7 +66,7 @@ impl<T: Copy> Mutable for TrieMap<T> {
}
}

impl<T: Copy> Map<uint, T> for TrieMap<T> {
impl<T> Map<uint, T> for TrieMap<T> {
/// Return true if the map contains a value for the specified key
#[inline(always)]
pure fn contains_key(&self, key: &uint) -> bool {
Expand Down Expand Up @@ -127,7 +128,7 @@ impl<T: Copy> Map<uint, T> for TrieMap<T> {
}
}

impl<T: Copy> TrieMap<T> {
impl<T> TrieMap<T> {
#[inline(always)]
static pure fn new() -> TrieMap<T> {
TrieMap{root: TrieNode::new(), length: 0}
Expand Down Expand Up @@ -209,10 +210,15 @@ struct TrieNode<T> {
children: [Child<T> * 16] // FIXME: #3469: can't use the SIZE constant yet
}

impl<T: Copy> TrieNode<T> {
impl<T> TrieNode<T> {
#[inline(always)]
static pure fn new() -> TrieNode<T> {
TrieNode{count: 0, children: [Nothing, ..SIZE]}
// FIXME: #5244: [Nothing, ..SIZE] should be possible without Copy
TrieNode{count: 0,
children: [Nothing, Nothing, Nothing, Nothing,
Nothing, Nothing, Nothing, Nothing,
Nothing, Nothing, Nothing, Nothing,
Nothing, Nothing, Nothing, Nothing]}
}
}

Expand Down Expand Up @@ -260,12 +266,16 @@ pure fn chunk(n: uint, idx: uint) -> uint {
(n >> (SHIFT * real_idx)) & MASK
}

fn insert<T: Copy>(count: &mut uint, child: &mut Child<T>, key: uint,
fn insert<T>(count: &mut uint, child: &mut Child<T>, key: uint,
value: T, idx: uint) -> bool {
match *child {
let mut tmp = Nothing;
tmp <-> *child;
let mut added = false;

*child = match tmp {
External(stored_key, stored_value) => {
if stored_key == key {
false // already in the trie
External(stored_key, value)
} else {
// conflict - split the node
let mut new = ~TrieNode::new();
Expand All @@ -274,20 +284,24 @@ fn insert<T: Copy>(count: &mut uint, child: &mut Child<T>, key: uint,
stored_key, stored_value, idx + 1);
insert(&mut new.count, &mut new.children[chunk(key, idx)], key,
value, idx + 1);
*child = Internal(new);
true
added = true;
Internal(new)
}
}
Internal(ref mut x) => {
insert(&mut x.count, &mut x.children[chunk(key, idx)], key, value,
idx + 1)
Internal(x) => {
let mut x = x;
added = insert(&mut x.count, &mut x.children[chunk(key, idx)], key,
value, idx + 1);
Internal(x)

}
Nothing => {
*count += 1;
*child = External(key, value);
true
added = true;
External(key, value)
}
}
};
added
}

fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
Expand Down