Skip to content

Commit 46cfe2c

Browse files
committed
---
yaml --- r: 148276 b: refs/heads/try2 c: e063e96 h: refs/heads/master v: v3
1 parent 6d33c00 commit 46cfe2c

File tree

2 files changed

+85
-35
lines changed

2 files changed

+85
-35
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: 431e2bb92372a6ba441b93917e53195e76fb565d
8+
refs/heads/try2: e063e96ec90544c9ffa811396d14541761656d07
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libstd/trie.rs

Lines changed: 84 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
1313
use prelude::*;
1414
use uint;
15-
use util::{swap, replace};
15+
use util::replace;
1616
use vec;
1717

1818
// FIXME: #5244: need to manually update the TrieNode constructor
@@ -415,39 +415,41 @@ fn find_mut<'r, T>(child: &'r mut Child<T>, key: uint, idx: uint) -> Option<&'r
415415

416416
fn insert<T>(count: &mut uint, child: &mut Child<T>, key: uint, value: T,
417417
idx: uint) -> Option<T> {
418-
let mut tmp = Nothing;
419-
let ret;
420-
swap(&mut tmp, child);
421-
422-
*child = match tmp {
423-
External(stored_key, stored_value) => {
424-
if stored_key == key {
425-
ret = Some(stored_value);
426-
External(stored_key, value)
427-
} else {
428-
// conflict - split the node
429-
let mut new = ~TrieNode::new();
430-
insert(&mut new.count,
431-
&mut new.children[chunk(stored_key, idx)],
432-
stored_key, stored_value, idx + 1);
433-
ret = insert(&mut new.count, &mut new.children[chunk(key, idx)],
434-
key, value, idx + 1);
435-
Internal(new)
436-
}
437-
}
438-
Internal(x) => {
439-
let mut x = x;
440-
ret = insert(&mut x.count, &mut x.children[chunk(key, idx)], key,
441-
value, idx + 1);
442-
Internal(x)
443-
}
444-
Nothing => {
445-
*count += 1;
446-
ret = None;
447-
External(key, value)
448-
}
449-
};
450-
return ret;
418+
// we branch twice to avoid having to do the `replace` when we
419+
// don't need to; this is much faster, especially for keys that
420+
// have long shared prefixes.
421+
match *child {
422+
Nothing => {
423+
*count += 1;
424+
*child = External(key, value);
425+
return None;
426+
}
427+
Internal(ref mut x) => {
428+
return insert(&mut x.count, &mut x.children[chunk(key, idx)], key, value, idx + 1);
429+
}
430+
External(stored_key, ref mut stored_value) if stored_key == key => {
431+
// swap in the new value and return the old.
432+
return Some(replace(stored_value, value));
433+
}
434+
_ => {}
435+
}
436+
437+
// conflict, an external node with differing keys: we have to
438+
// split the node, so we need the old value by value; hence we
439+
// have to move out of `child`.
440+
match replace(child, Nothing) {
441+
External(stored_key, stored_value) => {
442+
let mut new = ~TrieNode::new();
443+
insert(&mut new.count,
444+
&mut new.children[chunk(stored_key, idx)],
445+
stored_key, stored_value, idx + 1);
446+
let ret = insert(&mut new.count, &mut new.children[chunk(key, idx)],
447+
key, value, idx + 1);
448+
*child = Internal(new);
449+
return ret;
450+
}
451+
_ => unreachable!()
452+
}
451453
}
452454

453455
fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
@@ -886,6 +888,54 @@ mod bench_map {
886888
}
887889
});
888890
}
891+
892+
#[bench]
893+
fn bench_insert_large(bh: &mut BenchHarness) {
894+
let mut m = TrieMap::<[uint, .. 10]>::new();
895+
let mut rng = weak_rng();
896+
897+
bh.iter(|| {
898+
for _ in range(0, 1000) {
899+
m.insert(rng.gen(), [1, .. 10]);
900+
}
901+
})
902+
}
903+
#[bench]
904+
fn bench_insert_large_low_bits(bh: &mut BenchHarness) {
905+
let mut m = TrieMap::<[uint, .. 10]>::new();
906+
let mut rng = weak_rng();
907+
908+
bh.iter(|| {
909+
for _ in range(0, 1000) {
910+
// only have the last few bits set.
911+
m.insert(rng.gen::<uint>() & 0xff_ff, [1, .. 10]);
912+
}
913+
})
914+
}
915+
916+
#[bench]
917+
fn bench_insert_small(bh: &mut BenchHarness) {
918+
let mut m = TrieMap::<()>::new();
919+
let mut rng = weak_rng();
920+
921+
bh.iter(|| {
922+
for _ in range(0, 1000) {
923+
m.insert(rng.gen(), ());
924+
}
925+
})
926+
}
927+
#[bench]
928+
fn bench_insert_small_low_bits(bh: &mut BenchHarness) {
929+
let mut m = TrieMap::<()>::new();
930+
let mut rng = weak_rng();
931+
932+
bh.iter(|| {
933+
for _ in range(0, 1000) {
934+
// only have the last few bits set.
935+
m.insert(rng.gen::<uint>() & 0xff_ff, ());
936+
}
937+
})
938+
}
889939
}
890940

891941
#[cfg(test)]

0 commit comments

Comments
 (0)