Skip to content

Commit 2a2ea5e

Browse files
committed
Implement lower_bound_iter/upper_bound_iter for TrieMap/TrieSet
1 parent 094e426 commit 2a2ea5e

File tree

1 file changed

+102
-0
lines changed

1 file changed

+102
-0
lines changed

src/libstd/trie.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,53 @@ impl<T> TrieMap<T> {
156156
remaining_max: self.length
157157
}
158158
}
159+
160+
// If `upper` is true then returns upper_bound else returns lower_bound.
161+
#[inline]
162+
fn bound_iter<'a>(&'a self, key: uint, upper: bool) -> TrieMapIterator<'a, T> {
163+
let mut node: &'a TrieNode<T> = &self.root;
164+
let mut idx = 0;
165+
let mut it = TrieMapIterator {
166+
stack: ~[],
167+
remaining_min: 0,
168+
remaining_max: self.length
169+
};
170+
loop {
171+
let children = &node.children;
172+
let child_id = chunk(key, idx);
173+
match children[child_id] {
174+
Internal(ref n) => {
175+
node = &**n;
176+
it.stack.push(children.slice_from(child_id + 1).iter());
177+
}
178+
External(stored, _) => {
179+
if stored < key || (upper && stored == key) {
180+
it.stack.push(children.slice_from(child_id + 1).iter());
181+
} else {
182+
it.stack.push(children.slice_from(child_id).iter());
183+
}
184+
return it;
185+
}
186+
Nothing => {
187+
it.stack.push(children.slice_from(child_id + 1).iter());
188+
return it
189+
}
190+
}
191+
idx += 1;
192+
}
193+
}
194+
195+
/// Get an iterator pointing to the first key-value pair whose key is not less than `key`.
196+
/// If all keys in the map are less than `key` an empty iterator is returned.
197+
pub fn lower_bound_iter<'a>(&'a self, key: uint) -> TrieMapIterator<'a, T> {
198+
self.bound_iter(key, false)
199+
}
200+
201+
/// Get an iterator pointing to the first key-value pair whose key is greater than `key`.
202+
/// If all keys in the map are not greater than `key` an empty iterator is returned.
203+
pub fn upper_bound_iter<'a>(&'a self, key: uint) -> TrieMapIterator<'a, T> {
204+
self.bound_iter(key, true)
205+
}
159206
}
160207

161208
impl<T, Iter: Iterator<(uint, T)>> FromIterator<(uint, T), Iter> for TrieMap<T> {
@@ -233,6 +280,18 @@ impl TrieSet {
233280
pub fn iter<'a>(&'a self) -> TrieSetIterator<'a> {
234281
TrieSetIterator{iter: self.map.iter()}
235282
}
283+
284+
/// Get an iterator pointing to the first value that is not less than `val`.
285+
/// If all values in the set are less than `val` an empty iterator is returned.
286+
pub fn lower_bound_iter<'a>(&'a self, val: uint) -> TrieSetIterator<'a> {
287+
TrieSetIterator{iter: self.map.lower_bound_iter(val)}
288+
}
289+
290+
/// Get an iterator pointing to the first value that key is greater than `val`.
291+
/// If all values in the set are not greater than `val` an empty iterator is returned.
292+
pub fn upper_bound_iter<'a>(&'a self, val: uint) -> TrieSetIterator<'a> {
293+
TrieSetIterator{iter: self.map.upper_bound_iter(val)}
294+
}
236295
}
237296

238297
impl<Iter: Iterator<uint>> FromIterator<uint, Iter> for TrieSet {
@@ -645,6 +704,49 @@ mod test_map {
645704
}
646705
assert_eq!(i, last - first);
647706
}
707+
708+
#[test]
709+
fn test_bound_iter() {
710+
let empty_map : TrieMap<uint> = TrieMap::new();
711+
assert_eq!(empty_map.lower_bound_iter(0).next(), None);
712+
assert_eq!(empty_map.upper_bound_iter(0).next(), None);
713+
714+
let last = 999u;
715+
let step = 3u;
716+
let value = 42u;
717+
718+
let mut map : TrieMap<uint> = TrieMap::new();
719+
do uint::range_step(0u, last, step as int) |x| {
720+
assert!(x % step == 0);
721+
map.insert(x, value);
722+
true
723+
};
724+
725+
for i in range(0u, last - step) {
726+
let mut lb = map.lower_bound_iter(i);
727+
let mut ub = map.upper_bound_iter(i);
728+
let next_key = i - i % step + step;
729+
let next_pair = (next_key, &value);
730+
if (i % step == 0) {
731+
assert_eq!(lb.next(), Some((i, &value)));
732+
} else {
733+
assert_eq!(lb.next(), Some(next_pair));
734+
}
735+
assert_eq!(ub.next(), Some(next_pair));
736+
}
737+
738+
let mut lb = map.lower_bound_iter(last - step);
739+
assert_eq!(lb.next(), Some((last - step, &value)));
740+
let mut ub = map.upper_bound_iter(last - step);
741+
assert_eq!(ub.next(), None);
742+
743+
for i in range(last - step + 1, last) {
744+
let mut lb = map.lower_bound_iter(i);
745+
assert_eq!(lb.next(), None);
746+
let mut ub = map.upper_bound_iter(i);
747+
assert_eq!(ub.next(), None);
748+
}
749+
}
648750
}
649751

650752
#[cfg(test)]

0 commit comments

Comments
 (0)