Add goto_first() methods to SetCursor and MapCursor.

This commit is contained in:
Jakob Stoklund Olesen
2017-11-20 12:31:51 -08:00
parent 3389eaef29
commit a2ff2a6836
3 changed files with 40 additions and 3 deletions

View File

@@ -254,6 +254,11 @@ where
}) })
} }
/// Move this cursor to the first element.
pub fn goto_first(&mut self) -> Option<V> {
self.root.map(|root| self.path.first(root, self.pool).1)
}
/// Insert `(key, value))` into the map and leave the cursor at the inserted pair. /// Insert `(key, value))` into the map and leave the cursor at the inserted pair.
/// ///
/// If the map did not contain `key`, return `None`. /// If the map did not contain `key`, return `None`.
@@ -341,6 +346,8 @@ mod test {
assert_eq!(c.prev(), None); assert_eq!(c.prev(), None);
c.verify(); c.verify();
assert_eq!(c.tpath(), "<empty path>"); assert_eq!(c.tpath(), "<empty path>");
assert_eq!(c.goto_first(), None);
assert_eq!(c.tpath(), "<empty path>");
} }
#[test] #[test]
@@ -407,7 +414,7 @@ mod test {
{ {
let mut c = m.cursor(f, &()); let mut c = m.cursor(f, &());
assert_eq!(c.goto(0), None); assert_eq!(c.goto_first(), Some(4.0));
assert_eq!(c.key(), Some(40)); assert_eq!(c.key(), Some(40));
assert_eq!(c.value(), Some(4.0)); assert_eq!(c.value(), Some(4.0));
assert_eq!(c.next(), Some((50, 5.5))); assert_eq!(c.next(), Some((50, 5.5)));
@@ -516,6 +523,12 @@ mod test {
assert_eq!(m.tpath(810, f, &()), "node2[7]--node8[0]"); assert_eq!(m.tpath(810, f, &()), "node2[7]--node8[0]");
assert_eq!(m.tpath(870, f, &()), "node2[7]--node8[6]"); assert_eq!(m.tpath(870, f, &()), "node2[7]--node8[6]");
{
let mut c = m.cursor(f, &());
assert_eq!(c.goto_first(), Some(1.1));
assert_eq!(c.key(), Some(110));
}
// Front of first leaf. // Front of first leaf.
m.insert(0, 4.2, f, &()); m.insert(0, 4.2, f, &());
m.verify(f, &()); m.verify(f, &());

View File

@@ -87,6 +87,22 @@ impl<F: Forest> Path<F> {
unreachable!(); unreachable!();
} }
/// Move path to the first entry of the tree starting at `root` and return it.
pub fn first(&mut self, root: Node, pool: &NodePool<F>) -> (F::Key, F::Value) {
let mut node = root;
for level in 0.. {
self.size = level + 1;
self.node[level] = node;
self.entry[level] = 0;
match &pool[node] {
&NodeData::Inner { tree, .. } => node = tree[0],
&NodeData::Leaf { keys, vals, .. } => return (keys.borrow()[0], vals.borrow()[0]),
&NodeData::Free { .. } => panic!("Free {} reached from {}", node, root),
}
}
unreachable!();
}
/// Move this path to the next key-value pair and return it. /// Move this path to the next key-value pair and return it.
pub fn next(&mut self, pool: &NodePool<F>) -> Option<(F::Key, F::Value)> { pub fn next(&mut self, pool: &NodePool<F>) -> Option<(F::Key, F::Value)> {
match self.leaf_pos() { match self.leaf_pos() {

View File

@@ -216,6 +216,11 @@ where
} }
} }
/// Move this cursor to the first element.
pub fn goto_first(&mut self) -> Option<K> {
self.root.map(|root| self.path.first(root, self.pool).0)
}
/// Try to insert `elem` into the set and leave the cursor at the inserted element. /// Try to insert `elem` into the set and leave the cursor at the inserted element.
/// ///
/// If the set did not contain `elem`, insert it and return true. /// If the set did not contain `elem`, insert it and return true.
@@ -293,9 +298,12 @@ mod test {
s.clear(&mut f); s.clear(&mut f);
assert!(!s.contains(7, &f, &())); assert!(!s.contains(7, &f, &()));
let c = SetCursor::new(&mut s, &mut f, &()); let mut c = SetCursor::new(&mut s, &mut f, &());
c.verify(); c.verify();
assert_eq!(c.elem(), None); assert_eq!(c.elem(), None);
assert_eq!(c.goto_first(), None);
assert_eq!(c.tpath(), "<empty path>");
} }
#[test] #[test]
@@ -355,7 +363,7 @@ mod test {
} }
assert!(!c.is_empty()); assert!(!c.is_empty());
assert!(c.goto(0)); assert_eq!(c.goto_first(), Some(0));
assert_eq!(c.tpath(), "node2[0]--node0[0]"); assert_eq!(c.tpath(), "node2[0]--node0[0]");
assert_eq!(c.prev(), None); assert_eq!(c.prev(), None);