Skip to content

Commit 89e2578

Browse files
committed
trie: add find_mut method
1 parent d774333 commit 89e2578

File tree

1 file changed

+32
-1
lines changed

1 file changed

+32
-1
lines changed

src/libcore/trie.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ impl<T> Map<uint, T> for TrieMap<T> {
9090
self.root.mutate_values(f);
9191
}
9292

93-
/// Return the value corresponding to the key in the map
93+
/// Return a reference to the value corresponding to the key
9494
#[inline(hint)]
9595
fn find(&self, key: &uint) -> Option<&'self T> {
9696
let mut node: &'self TrieNode<T> = &self.root;
@@ -153,6 +153,12 @@ pub impl<T> TrieMap<T> {
153153
fn each_value_reverse(&self, f: &fn(&T) -> bool) {
154154
self.each_reverse(|&(_, v)| f(v))
155155
}
156+
157+
/// Return a mutable reference to the value corresponding to the key
158+
#[inline(always)]
159+
fn find_mut(&mut self, key: &uint) -> Option<&'self mut T> {
160+
find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1)
161+
}
156162
}
157163

158164
pub struct TrieSet {
@@ -276,6 +282,17 @@ fn chunk(n: uint, idx: uint) -> uint {
276282
(n >> sh) & MASK
277283
}
278284

285+
fn find_mut<T>(child: &'r mut Child<T>, key: uint, idx: uint) -> Option<&'r mut T> {
286+
unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
287+
(match *child {
288+
External(_, ref value) => Some(cast::transmute_mut(value)),
289+
Internal(ref x) => find_mut(cast::transmute_mut(&x.children[chunk(key, idx)]),
290+
key, idx + 1),
291+
Nothing => None
292+
}).map_consume(|x| cast::transmute_mut_region(x))
293+
}
294+
}
295+
279296
fn insert<T>(count: &mut uint, child: &mut Child<T>, key: uint, value: T,
280297
idx: uint) -> bool {
281298
let mut tmp = Nothing;
@@ -357,8 +374,22 @@ pub fn check_integrity<T>(trie: &TrieNode<T>) {
357374
#[cfg(test)]
358375
mod tests {
359376
use super::*;
377+
use core::option::{Some, None};
360378
use uint;
361379

380+
#[test]
381+
fn test_find_mut() {
382+
let mut m = TrieMap::new();
383+
fail_unless!(m.insert(1, 12));
384+
fail_unless!(m.insert(2, 8));
385+
fail_unless!(m.insert(5, 14));
386+
let new = 100;
387+
match m.find_mut(&5) {
388+
None => fail!(), Some(x) => *x = new
389+
}
390+
assert_eq!(m.find(&5), Some(&new));
391+
}
392+
362393
#[test]
363394
fn test_step() {
364395
let mut trie = TrieMap::new();

0 commit comments

Comments
 (0)