Skip to content

Commit b61d278

Browse files
committed
streamline the postorder iterator
1 parent c366071 commit b61d278

File tree

1 file changed

+35
-59
lines changed

1 file changed

+35
-59
lines changed

src/trees.rs

Lines changed: 35 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -686,87 +686,63 @@ impl NodeIterator for PreorderNodeIterator<'_> {
686686
iterator_for_nodeiterator!(PreorderNodeIterator<'_>);
687687

688688
struct PostorderNodeIterator<'a> {
689-
//root_stack: Vec<NodeId>,
690689
nodes: Vec<NodeId>,
691-
tree: &'a Tree,
692690
current_node_index: usize,
693691
num_nodes_current_tree: usize,
692+
// Make the lifetime checker happy.
693+
tree: std::marker::PhantomData<&'a Tree>,
694694
}
695695

696696
impl<'a> PostorderNodeIterator<'a> {
697697
fn new(tree: &'a Tree) -> Self {
698-
let mut rv = PostorderNodeIterator {
699-
//root_stack: tree.roots_to_vec(),
700-
nodes: vec![
698+
let mut num_nodes_current_tree: usize = 0;
699+
let ptr = std::ptr::addr_of_mut!(num_nodes_current_tree);
700+
let mut nodes = vec![
701701
NodeId::NULL;
702702
// NOTE: this fn does not return error codes
703703
unsafe { ll_bindings::tsk_tree_get_size_bound(tree.inner) } as usize
704-
],
705-
tree,
706-
current_node_index: 0,
707-
num_nodes_current_tree: 0,
708-
};
709-
//rv.root_stack.reverse();
710-
// if let Some(root) = rv.root_stack.pop() {
711-
// // hmm--iterator setup shouldn't be
712-
// // able to fail...
713-
// // The error codes can be:
714-
// // * out of memory
715-
// // * node out of bounds, which "can't be" possible here?
716-
// let _ret = rv.update_nodes(NodeId::NULL);
717-
// }
718-
let _ret = rv.update_nodes(NodeId::NULL);
719-
rv
720-
}
704+
];
721705

722-
fn update_nodes(&mut self, u: NodeId) -> i32 {
723-
let ptr = std::ptr::addr_of_mut!(self.num_nodes_current_tree);
724-
725-
unsafe {
706+
let rv = unsafe {
726707
ll_bindings::tsk_tree_postorder(
727-
self.tree.inner,
728-
u.into(),
729-
self.nodes.as_mut_ptr() as *mut tsk_id_t,
708+
tree.inner,
709+
NodeId::NULL.into(), // start from virtual root
710+
nodes.as_mut_ptr() as *mut tsk_id_t,
730711
ptr as *mut tsk_size_t,
731712
)
713+
};
714+
715+
// This is either out of memory
716+
// or node out of range.
717+
// The former is fatal, and the latter
718+
// not relevant (for now), as we start at roots.
719+
if rv < 0 {
720+
panic!("fatal error calculating postoder node list");
732721
}
733-
}
734-
}
735722

736-
impl NodeIterator for PostorderNodeIterator<'_> {
737-
fn next_node(&mut self) {
738-
//match self.current_node_index < self.num_nodes_current_tree {
739-
// true => (),
740-
// false => {
741-
// match self.root_stack.pop() {
742-
// Some(root) => {
743-
// self.current_node_index = 0;
744-
// //FIXME: failure should not be an option.
745-
// let _ret = self.update_nodes(root);
746-
// }
747-
// None => {
748-
// // should be sufficient to terminate iteration
749-
// self.current_node_index = 0;
750-
// self.num_nodes_current_tree = 0;
751-
// }
752-
// }
753-
// }
754-
//}
723+
Self {
724+
nodes,
725+
current_node_index: 0,
726+
num_nodes_current_tree,
727+
tree: std::marker::PhantomData,
728+
}
755729
}
730+
}
756731

757-
fn current_node(&mut self) -> Option<NodeId> {
758-
if self.current_node_index < self.num_nodes_current_tree {
759-
let rv = Some(self.nodes[self.current_node_index]);
760-
self.current_node_index += 1;
761-
rv
762-
} else {
763-
None
732+
impl<'a> Iterator for PostorderNodeIterator<'a> {
733+
type Item = NodeId;
734+
fn next(&mut self) -> Option<Self::Item> {
735+
match self.current_node_index < self.num_nodes_current_tree {
736+
true => {
737+
let rv = self.nodes[self.current_node_index];
738+
self.current_node_index += 1;
739+
Some(rv)
740+
}
741+
false => None,
764742
}
765743
}
766744
}
767745

768-
iterator_for_nodeiterator!(PostorderNodeIterator<'_>);
769-
770746
struct RootIterator<'a> {
771747
current_root: Option<NodeId>,
772748
next_root: NodeId,

0 commit comments

Comments
 (0)