Skip to content

Commit ed6b60a

Browse files
thestingergraydon
authored andcommitted
---
yaml --- r: 41788 b: refs/heads/master c: 9cc9a75 h: refs/heads/master v: v3
1 parent 36deb65 commit ed6b60a

File tree

2 files changed

+71
-3
lines changed

2 files changed

+71
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 7f754764d60e79752c7cca1f8289eedeb469cad0
2+
refs/heads/master: 9cc9a7582c11201c76745f4d190aaa21f4073e32
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 2f46b763da2c098913884f101b6d71d69af41b49
55
refs/heads/try: 3d5418789064fdb463e872a4e651af1c628a3650

trunk/src/libstd/treemap.rs

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ use core::prelude::*;
2323
// as a right child. The time complexity is the same, and re-balancing
2424
// operations are more frequent but also cheaper.
2525

26-
// TODO: lazy iteration, for O(n) Eq and set operations instead of O(n*log(m))
27-
2826
// TODO: implement Ord for TreeSet
2927
// could be superset/subset-based or in-order lexicographic comparison... but
3028
// there are methods for is_superset/is_subset so lexicographic is more useful
@@ -138,8 +136,43 @@ impl <K: Ord, V> TreeMap<K, V> {
138136
if ret { self.length -= 1 }
139137
ret
140138
}
139+
140+
/// Get a lazy iterator over the nodes in the map. Requires that it
141+
/// be frozen (immutable).
142+
fn iter(&self) -> TreeMapIterator/&self<K, V> {
143+
TreeMapIterator{stack: ~[], node: &self.root}
144+
}
145+
}
146+
147+
/// Lazy forward iterator over a map
148+
pub struct TreeMapIterator<K: Ord, V> {
149+
priv stack: ~[&~TreeNode<K, V>],
150+
priv node: &Option<~TreeNode<K, V>>
141151
}
142152

153+
impl <K: Ord, V> TreeMapIterator<K, V> {
154+
/// Advance the iterator to the next node (in order) and return a
155+
/// tuple with a reference to the key and value. If there are no
156+
/// more nodes, return None.
157+
fn next(&mut self) -> Option<(&self/K, &self/V)> {
158+
while self.stack.is_not_empty() || self.node.is_some() {
159+
match *self.node {
160+
Some(ref x) => {
161+
self.stack.push(x);
162+
self.node = &x.left;
163+
}
164+
None => {
165+
let res = self.stack.pop();
166+
self.node = &res.right;
167+
return Some((&res.key, &res.value));
168+
}
169+
}
170+
}
171+
None
172+
}
173+
}
174+
175+
143176
pub struct TreeSet<T: Ord> {
144177
priv map: TreeMap<T, ()>
145178
}
@@ -611,6 +644,41 @@ mod test_treemap {
611644
assert b.insert(5, 19);
612645
assert a == b;
613646
}
647+
648+
#[test]
649+
fn test_lazy_iterator() {
650+
let mut m = TreeMap::new();
651+
let (x1, y1) = (2, 5);
652+
let (x2, y2) = (9, 12);
653+
let (x3, y3) = (20, -3);
654+
let (x4, y4) = (29, 5);
655+
let (x5, y5) = (103, 3);
656+
657+
assert m.insert(x1, y1);
658+
assert m.insert(x2, y2);
659+
assert m.insert(x3, y3);
660+
assert m.insert(x4, y4);
661+
assert m.insert(x5, y5);
662+
663+
let m = m;
664+
let mut iter = m.iter();
665+
666+
// ICE:
667+
//assert iter.next() == Some((&x1, &y1));
668+
//assert iter.next().eq(&Some((&x1, &y1)));
669+
670+
assert iter.next().unwrap() == (&x1, &y1);
671+
assert iter.next().unwrap() == (&x2, &y2);
672+
assert iter.next().unwrap() == (&x3, &y3);
673+
assert iter.next().unwrap() == (&x4, &y4);
674+
assert iter.next().unwrap() == (&x5, &y5);
675+
676+
// ICE:
677+
//assert iter.next() == None;
678+
//assert iter.next().eq(&None);
679+
680+
assert iter.next().is_none();
681+
}
614682
}
615683

616684
#[cfg(test)]

0 commit comments

Comments
 (0)