Skip to content

Commit 8ddd286

Browse files
committed
auto merge of #15540 : Gankro/rust/master, r=huonw
Removing recursion from TreeMap implementation, because we don't have TCO. No need to add ```O(logn)``` extra stack frames to search in a tree. I find it curious that ```find_mut``` and ```find``` basically duplicated the same logic, but in different ways (iterative vs recursive), possibly to maneuvre around mutability rules, but that's a more fundamental issue to deal with elsewhere. Thanks to acrichto for the magic trick to appease borrowck (another issue to deal with elsewhere).
2 parents b53f3e7 + 03981b5 commit 8ddd286

File tree

1 file changed

+15
-17
lines changed

1 file changed

+15
-17
lines changed

src/libcollections/treemap.rs

+15-17
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl<K: Ord, V> Mutable for TreeMap<K, V> {
8989

9090
impl<K: Ord, V> Map<K, V> for TreeMap<K, V> {
9191
fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
92-
let mut current: &'a Option<Box<TreeNode<K, V>>> = &self.root;
92+
let mut current = &self.root;
9393
loop {
9494
match *current {
9595
Some(ref r) => {
@@ -108,7 +108,20 @@ impl<K: Ord, V> Map<K, V> for TreeMap<K, V> {
108108
impl<K: Ord, V> MutableMap<K, V> for TreeMap<K, V> {
109109
#[inline]
110110
fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
111-
find_mut(&mut self.root, key)
111+
let mut current = &mut self.root;
112+
loop {
113+
let temp = current; // hack to appease borrowck
114+
match *temp {
115+
Some(ref mut r) => {
116+
match key.cmp(&r.key) {
117+
Less => current = &mut r.left,
118+
Greater => current = &mut r.right,
119+
Equal => return Some(&mut r.value)
120+
}
121+
}
122+
None => return None
123+
}
124+
}
112125
}
113126

114127
fn swap(&mut self, key: K, value: V) -> Option<V> {
@@ -840,21 +853,6 @@ fn split<K: Ord, V>(node: &mut Box<TreeNode<K, V>>) {
840853
}
841854
}
842855

843-
fn find_mut<'r, K: Ord, V>(node: &'r mut Option<Box<TreeNode<K, V>>>,
844-
key: &K)
845-
-> Option<&'r mut V> {
846-
match *node {
847-
Some(ref mut x) => {
848-
match key.cmp(&x.key) {
849-
Less => find_mut(&mut x.left, key),
850-
Greater => find_mut(&mut x.right, key),
851-
Equal => Some(&mut x.value),
852-
}
853-
}
854-
None => None
855-
}
856-
}
857-
858856
fn insert<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
859857
key: K, value: V) -> Option<V> {
860858
match *node {

0 commit comments

Comments
 (0)