treemap: cut down on swap_unwrap in remove
Performance before:
std::treemap::TreeMap
sequential_ints 0.083971 s
random_ints 0.095861 s
delete_ints 0.083931 s
sequential_strings 0.278272 s
random_strings 0.240286 s
delete_strings 0.173581 s
Performance after:
std::treemap::TreeMap
sequential_ints 0.083297 s
random_ints 0.097644 s
delete_ints 0.052602 s
sequential_strings 0.287326 s
random_strings 0.242372 s
delete_strings 0.142269 s
This commit is contained in:
parent
b0f58f6e68
commit
f9c7ba009b
1 changed files with 21 additions and 15 deletions
|
|
@ -626,7 +626,7 @@ fn insert<K: Ord, V>(node: &mut Option<~TreeNode<K, V>>, key: K,
|
|||
}
|
||||
|
||||
fn remove<K: Ord, V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> bool {
|
||||
fn heir_swap<K: Ord, V>(node: &mut TreeNode<K, V>,
|
||||
fn heir_swap<K: Ord, V>(node: &mut ~TreeNode<K, V>,
|
||||
child: &mut Option<~TreeNode<K, V>>) {
|
||||
// *could* be done without recursion, but it won't borrow check
|
||||
do child.mutate |mut child| {
|
||||
|
|
@ -640,15 +640,15 @@ fn remove<K: Ord, V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
if node.is_none() {
|
||||
match *node {
|
||||
None => {
|
||||
return false // bottom of tree
|
||||
} else {
|
||||
let mut save = node.swap_unwrap();
|
||||
|
||||
let removed = if save.key < *key {
|
||||
remove(&mut save.right, key)
|
||||
}
|
||||
Some(ref mut save) => {
|
||||
let (removed, this) = if save.key < *key {
|
||||
(remove(&mut save.right, key), false)
|
||||
} else if *key < save.key {
|
||||
remove(&mut save.left, key)
|
||||
(remove(&mut save.left, key), false)
|
||||
} else {
|
||||
if save.left.is_some() {
|
||||
if save.right.is_some() {
|
||||
|
|
@ -662,16 +662,22 @@ fn remove<K: Ord, V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> bool {
|
|||
save.left = Some(left);
|
||||
remove(&mut save.left, key);
|
||||
} else {
|
||||
save = save.left.swap_unwrap();
|
||||
*save = save.left.swap_unwrap();
|
||||
}
|
||||
(true, false)
|
||||
} else if save.right.is_some() {
|
||||
save = save.right.swap_unwrap();
|
||||
*save = save.right.swap_unwrap();
|
||||
(true, false)
|
||||
} else {
|
||||
return true // leaf
|
||||
(true, true)
|
||||
}
|
||||
true
|
||||
};
|
||||
|
||||
if this {
|
||||
*node = None;
|
||||
return true;
|
||||
}
|
||||
|
||||
let left_level = save.left.map_default(0, |x| x.level);
|
||||
let right_level = save.right.map_default(0, |x| x.level);
|
||||
|
||||
|
|
@ -683,7 +689,7 @@ fn remove<K: Ord, V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> bool {
|
|||
do save.right.mutate |mut x| { x.level = save.level; x }
|
||||
}
|
||||
|
||||
skew(&mut save);
|
||||
skew(save);
|
||||
|
||||
match save.right {
|
||||
Some(ref mut right) => {
|
||||
|
|
@ -696,15 +702,15 @@ fn remove<K: Ord, V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> bool {
|
|||
None => ()
|
||||
}
|
||||
|
||||
split(&mut save);
|
||||
split(save);
|
||||
match save.right {
|
||||
Some(ref mut x) => { split(x) },
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
|
||||
*node = Some(save);
|
||||
removed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue