diff --git a/src/common/succinct_tree.rs b/src/common/succinct_tree.rs index d49a35ea11faf800613dbc7b7b9e02ee8e6bbe2a..52331e0828b2a292b378b98cae58d6501d5afe3a 100644 --- a/src/common/succinct_tree.rs +++ b/src/common/succinct_tree.rs @@ -9,7 +9,7 @@ pub trait SuccinctTree<T, Label>: Debug { fn parent(&self, index: u64) -> Result<u64, NodeError>; fn first_child(&self, index: u64) -> Result<u64, NodeError>; fn next_sibling(&self, index: u64) -> Result<u64, NodeError>; - fn from_id_tree(tree: Tree<i32>) -> Result<T, EmptyTreeError>; + fn from_id_tree(tree: Tree<Label>) -> Result<T, EmptyTreeError>; fn child_label(&self, index: u64) -> Result<&Label, NodeError>; fn labeled_child(&self, index: u64, label: Label) -> Result<u64, NodeError>; diff --git a/src/trees/bp_tree.rs b/src/trees/bp_tree.rs index cecf07840d063ad4f7363e55c9ba960d3ee08168..bb1749a2f2856cb22bc725c723d509c1e6ea9482 100644 --- a/src/trees/bp_tree.rs +++ b/src/trees/bp_tree.rs @@ -51,13 +51,13 @@ pub struct BPTree<L> { minmax: MinMax, } -impl<L> PartialEq for BPTree<L> { +impl<L: PartialEq + Clone> PartialEq for BPTree<L> { fn eq(&self, other: &Self) -> bool { self.rankselect.bits() == other.rankselect.bits() } } -impl<L> SuccinctTree<BPTree<L>, L> for BPTree<L> { +impl<L: PartialEq + Clone> SuccinctTree<BPTree<L>, L> for BPTree<L> { /// Checks if a node is a leaf. /// # Arguments /// * `index` The index of the node to check @@ -102,6 +102,7 @@ impl<L> SuccinctTree<BPTree<L>, L> for BPTree<L> { /// * `index` The index of the node to get the next sibling of. /// # Errors /// * `NotANodeError` If `index` does not reference a node. + /// * `NoSiblingError` If `index` has no further siblings. fn next_sibling(&self, index: u64) -> Result<u64, NodeError> { let parent_a = self.parent(index)?; let sibling = self.minmax.find_close(index)? + 1; @@ -118,9 +119,13 @@ impl<L> SuccinctTree<BPTree<L>, L> for BPTree<L> { /// * `tree` The IDTree which should be converted /// # Errors /// * `EmptyTreeError` If `tree` does not contain any nodes. - fn from_id_tree(tree: Tree<i32>) -> Result<Self, EmptyTreeError> { + fn from_id_tree(tree: Tree<L>) -> Result<Self, EmptyTreeError> { + let mut labels: Vec<L> = Vec::new(); let bitvec = if tree.height() > 0 { let root_id: &NodeId = tree.root_node_id().unwrap(); + for node in tree.traverse_pre_order(root_id).unwrap() { + labels.push(node.data().clone()); + } Self::traverse_id_tree_for_bitvec(tree.get(root_id).unwrap(), &tree) } else { return Err(EmptyTreeError); @@ -130,7 +135,7 @@ impl<L> SuccinctTree<BPTree<L>, L> for BPTree<L> { Ok(Self { rankselect: RankSelect::new(bitvec.clone(), superblock_size as usize), minmax: MinMax::new(bitvec.clone(), 1024), - labels: Vec::with_capacity(bitvec.len() as usize), + labels: labels, }) } @@ -138,9 +143,13 @@ impl<L> SuccinctTree<BPTree<L>, L> for BPTree<L> { /// # Arguments /// * `index` The index of the node to get the label of /// # Errors + /// * `NotANodeError` If `index` does not reference a node. /// * `NoLabelError` If `index` does not reference a node with a label. fn child_label(&self, index: u64) -> Result<&L, NodeError> { - self.labels.get(index as usize).ok_or(NodeError::NoLabelError) + self.is_valid_index(index)?; + self.labels + .get(index as usize) + .ok_or(NodeError::NoLabelError) } /// Returns the child from the specified node with that label @@ -148,20 +157,28 @@ impl<L> SuccinctTree<BPTree<L>, L> for BPTree<L> { /// * `index` The index of the node to analyze /// * `label` The label which a should have /// # Errors + /// * `NotANodeError` If `index` does not reference a node. /// * `NoSuchChildError` If there is no child which has this label fn labeled_child(&self, index: u64, label: L) -> Result<u64, NodeError> { - unimplemented!(); - + self.is_valid_index(index)?; + let first_child = self.first_child(index)?; + while self.next_sibling(first_child).err().is_none() { + let sibling: u64 = self.next_sibling(index)?; + if *self.child_label(sibling)? == label { + return Ok(sibling); + } + } + Err(NodeError::NoSuchChildError) } } -impl<L> Debug for BPTree<L> { +impl<L: PartialEq + Clone> Debug for BPTree<L> { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "BPTree\n {{ bits: {:?} }}", self.rankselect.bits()) } } -impl<L> BPTree<L> { +impl<L: PartialEq + Clone> BPTree<L> { /// Returns whether the index is valid /// # Arguments /// * `index` The index which should be valid @@ -264,7 +281,7 @@ impl<L> BPTree<L> { Ok(()) } - fn traverse_id_tree_for_bitvec(node: &Node<i32>, tree: &Tree<i32>) -> BitVec<u8> { + fn traverse_id_tree_for_bitvec(node: &Node<L>, tree: &Tree<L>) -> BitVec<u8> { let mut bitvec = BitVec::new(); bitvec.push(true); for child in node.children() { @@ -451,7 +468,7 @@ mod tests { #[test] fn traverse_id_tree_for_bitvec() { let bitvec = bit_vec!(true, true, true, false, false, true, false, false); - let expected_tree: BPTree<String> = BPTree::from_bitvec(bitvec.clone()).unwrap(); + let expected_tree: BPTree<i32> = BPTree::from_bitvec(bitvec.clone()).unwrap(); let mut id_tree: Tree<i32> = TreeBuilder::new().with_node_capacity(5).build(); let root_id: NodeId = id_tree.insert(Node::new(0), AsRoot).unwrap(); let child_id = id_tree.insert(Node::new(1), UnderNode(&root_id)).unwrap(); @@ -464,7 +481,7 @@ mod tests { #[test] fn from_empty_id_tree() { let id_tree: Tree<i32> = TreeBuilder::new().with_node_capacity(5).build(); - let bp_tree: Result<BPTree<String>, EmptyTreeError> = BPTree::from_id_tree(id_tree); + let bp_tree: Result<BPTree<i32>, EmptyTreeError> = BPTree::from_id_tree(id_tree); assert_eq!(bp_tree.unwrap_err(), EmptyTreeError); } @@ -478,4 +495,11 @@ mod tests { "BPTree\n { bits: bit_vec![true, true, false, true, false, false] }" ) } + + #[test] + fn child_label() { + let id_tree: Tree<i32> = TreeBuilder::new().with_node_capacity(5).build(); + let bp_tree: Result<BPTree<i32>, EmptyTreeError> = BPTree::from_id_tree(id_tree); + assert_eq!(bp_tree.unwrap_err(), EmptyTreeError); + } } diff --git a/src/trees/louds_tree.rs b/src/trees/louds_tree.rs index 4944a709580c2466f7e07d7331b6869db00e5d11..d774782a6e87e74a8cb007263dad00c2df259fca 100644 --- a/src/trees/louds_tree.rs +++ b/src/trees/louds_tree.rs @@ -132,7 +132,7 @@ impl<L> SuccinctTree<LOUDSTree<L>, L> for LOUDSTree<L> { /// * `tree` The IDTree which should be converted /// # Errors /// * `EmptyTreeError` If `tree` does not contain any nodes. - fn from_id_tree(tree: Tree<i32>) -> Result<Self, EmptyTreeError> { + fn from_id_tree(tree: Tree<L>) -> Result<Self, EmptyTreeError> { let root = match tree.root_node_id() { Some(id) => id, None => return Err(EmptyTreeError), @@ -396,7 +396,7 @@ mod tests { let child_id = id_tree.insert(Node::new(1), UnderNode(&root_id)).unwrap(); id_tree.insert(Node::new(2), UnderNode(&root_id)).unwrap(); id_tree.insert(Node::new(3), UnderNode(&child_id)).unwrap(); - let tree: LOUDSTree<String> = LOUDSTree::from_id_tree(id_tree).unwrap(); + let tree: LOUDSTree<i32> = LOUDSTree::from_id_tree(id_tree).unwrap(); let bitvec = bit_vec![true, true, true, false, true, false, false, false]; let other_tree = LOUDSTree::from_bitvec(bitvec).unwrap(); assert_eq!(tree, other_tree) @@ -405,7 +405,7 @@ mod tests { #[test] fn from_empty_id_tree() { let id_tree: Tree<i32> = TreeBuilder::new().with_node_capacity(5).build(); - let tree: Result<LOUDSTree<String>, EmptyTreeError> = LOUDSTree::from_id_tree(id_tree); + let tree: Result<LOUDSTree<i32>, EmptyTreeError> = LOUDSTree::from_id_tree(id_tree); assert_eq!(tree.unwrap_err(), EmptyTreeError); } } diff --git a/testdata/loudstree.testdata b/testdata/loudstree.testdata index ac0a2e98f3f34d0c45be2761adbb3ad9e18ea5c3..68cb36629d38de3185f7622e7431de582f3bf7e8 100644 Binary files a/testdata/loudstree.testdata and b/testdata/loudstree.testdata differ