Skip to content

Commit a0643ee

Browse files
committed
std::trie: add an mutable-values iterator.
1 parent 1f1838e commit a0643ee

File tree

1 file changed

+168
-0
lines changed

1 file changed

+168
-0
lines changed

src/libstd/trie.rs

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,16 @@ impl<T> TrieMap<T> {
156156
}
157157
}
158158

159+
/// Get an iterator over the key-value pairs in the map, with the
160+
/// ability to mutate the values.
161+
pub fn mut_iter<'a>(&'a mut self) -> TrieMapMutIterator<'a, T> {
162+
TrieMapMutIterator {
163+
stack: ~[self.root.children.mut_iter()],
164+
remaining_min: self.length,
165+
remaining_max: self.length
166+
}
167+
}
168+
159169
// If `upper` is true then returns upper_bound else returns lower_bound.
160170
#[inline]
161171
fn bound<'a>(&'a self, key: uint, upper: bool) -> TrieMapIterator<'a, T> {
@@ -202,6 +212,63 @@ impl<T> TrieMap<T> {
202212
pub fn upper_bound<'a>(&'a self, key: uint) -> TrieMapIterator<'a, T> {
203213
self.bound(key, true)
204214
}
215+
// If `upper` is true then returns upper_bound else returns lower_bound.
216+
#[inline]
217+
fn mut_bound<'a>(&'a mut self, key: uint, upper: bool) -> TrieMapMutIterator<'a, T> {
218+
// we need an unsafe pointer here because we are borrowing
219+
// references to the internals of each of these
220+
// nodes.
221+
//
222+
// However, we're allowed to flaunt rustc like this because we
223+
// never actually modify the "shape" of the nodes. The only
224+
// place that mutation is can actually occur is of the actual
225+
// values of the TrieMap (as the return value of the
226+
// iterator), i.e. we can never cause a deallocation of any
227+
// TrieNodes so this pointer is always valid.
228+
let mut node = &mut self.root as *mut TrieNode<T>;
229+
230+
let mut idx = 0;
231+
let mut it = TrieMapMutIterator {
232+
stack: ~[],
233+
remaining_min: 0,
234+
remaining_max: self.length
235+
};
236+
loop {
237+
let children = unsafe {&mut (*node).children};
238+
let child_id = chunk(key, idx);
239+
match children[child_id] {
240+
Internal(ref mut n) => {
241+
node = &mut **n as *mut TrieNode<T>;
242+
}
243+
External(stored, _) => {
244+
if stored < key || (upper && stored == key) {
245+
it.stack.push(children.mut_slice_from(child_id + 1).mut_iter());
246+
} else {
247+
it.stack.push(children.mut_slice_from(child_id).mut_iter());
248+
}
249+
return it;
250+
}
251+
Nothing => {
252+
it.stack.push(children.mut_slice_from(child_id + 1).mut_iter());
253+
return it
254+
}
255+
}
256+
it.stack.push(children.mut_slice_from(child_id + 1).mut_iter());
257+
idx += 1;
258+
}
259+
}
260+
261+
/// Get an iterator pointing to the first key-value pair whose key is not less than `key`.
262+
/// If all keys in the map are less than `key` an empty iterator is returned.
263+
pub fn mut_lower_bound<'a>(&'a mut self, key: uint) -> TrieMapMutIterator<'a, T> {
264+
self.mut_bound(key, false)
265+
}
266+
267+
/// Get an iterator pointing to the first key-value pair whose key is greater than `key`.
268+
/// If all keys in the map are not greater than `key` an empty iterator is returned.
269+
pub fn mut_upper_bound<'a>(&'a mut self, key: uint) -> TrieMapMutIterator<'a, T> {
270+
self.mut_bound(key, true)
271+
}
205272
}
206273

207274
impl<T> FromIterator<(uint, T)> for TrieMap<T> {
@@ -482,6 +549,47 @@ impl<'a, T> Iterator<(uint, &'a T)> for TrieMapIterator<'a, T> {
482549
}
483550
}
484551

552+
/// Forward iterator over the key-value pairs of a map, with the
553+
/// values being mutable.
554+
pub struct TrieMapMutIterator<'a, T> {
555+
priv stack: ~[vec::VecMutIterator<'a, Child<T>>],
556+
priv remaining_min: uint,
557+
priv remaining_max: uint
558+
}
559+
560+
impl<'a, T> Iterator<(uint, &'a mut T)> for TrieMapMutIterator<'a, T> {
561+
fn next(&mut self) -> Option<(uint, &'a mut T)> {
562+
while !self.stack.is_empty() {
563+
match self.stack[self.stack.len() - 1].next() {
564+
None => {
565+
self.stack.pop();
566+
}
567+
Some(child) => {
568+
match *child {
569+
Internal(ref mut node) => {
570+
self.stack.push(node.children.mut_iter());
571+
}
572+
External(key, ref mut value) => {
573+
self.remaining_max -= 1;
574+
if self.remaining_min > 0 {
575+
self.remaining_min -= 1;
576+
}
577+
return Some((key, value));
578+
}
579+
Nothing => {}
580+
}
581+
}
582+
}
583+
}
584+
return None;
585+
}
586+
587+
#[inline]
588+
fn size_hint(&self) -> (uint, Option<uint>) {
589+
(self.remaining_min, Some(self.remaining_max))
590+
}
591+
}
592+
485593
/// Forward iterator over a set
486594
pub struct TrieSetIterator<'a> {
487595
priv iter: TrieMapIterator<'a, ()>
@@ -712,6 +820,30 @@ mod test_map {
712820
assert_eq!(i, last - first);
713821
}
714822

823+
#[test]
824+
fn test_mut_iter() {
825+
let mut empty_map : TrieMap<uint> = TrieMap::new();
826+
assert!(empty_map.mut_iter().next().is_none());
827+
828+
let first = uint::max_value - 10000;
829+
let last = uint::max_value;
830+
831+
let mut map = TrieMap::new();
832+
for x in range(first, last).invert() {
833+
map.insert(x, x / 2);
834+
}
835+
836+
let mut i = 0;
837+
for (k, v) in map.mut_iter() {
838+
assert_eq!(k, first + i);
839+
*v -= k / 2;
840+
i += 1;
841+
}
842+
assert_eq!(i, last - first);
843+
844+
assert!(map.iter().all(|(_, &v)| v == 0));
845+
}
846+
715847
#[test]
716848
fn test_bound() {
717849
let empty_map : TrieMap<uint> = TrieMap::new();
@@ -753,6 +885,42 @@ mod test_map {
753885
assert_eq!(ub.next(), None);
754886
}
755887
}
888+
889+
#[test]
890+
fn test_mut_bound() {
891+
let empty_map : TrieMap<uint> = TrieMap::new();
892+
assert_eq!(empty_map.lower_bound(0).next(), None);
893+
assert_eq!(empty_map.upper_bound(0).next(), None);
894+
895+
let mut m_lower = TrieMap::new();
896+
let mut m_upper = TrieMap::new();
897+
for i in range(0u, 100) {
898+
m_lower.insert(2 * i, 4 * i);
899+
m_upper.insert(2 * i, 4 * i);
900+
}
901+
902+
for i in range(0u, 199) {
903+
let mut lb_it = m_lower.mut_lower_bound(i);
904+
let (k, v) = lb_it.next().unwrap();
905+
let lb = i + i % 2;
906+
assert_eq!(lb, k);
907+
*v -= k;
908+
}
909+
910+
for i in range(0u, 198) {
911+
let mut ub_it = m_upper.mut_upper_bound(i);
912+
let (k, v) = ub_it.next().unwrap();
913+
let ub = i + 2 - i % 2;
914+
assert_eq!(ub, k);
915+
*v -= k;
916+
}
917+
918+
assert!(m_lower.mut_lower_bound(199).next().is_none());
919+
assert!(m_upper.mut_upper_bound(198).next().is_none());
920+
921+
assert!(m_lower.iter().all(|(_, &x)| x == 0));
922+
assert!(m_upper.iter().all(|(_, &x)| x == 0));
923+
}
756924
}
757925

758926
#[cfg(test)]

0 commit comments

Comments
 (0)