Skip to content
Snippets Groups Projects
Verified Commit 6a968c90 authored by Kevin Kaßelmann's avatar Kevin Kaßelmann Committed by David Mehren
Browse files

BPTree Label Ops

parent b82c8097
Branches
No related tags found
No related merge requests found
...@@ -9,7 +9,7 @@ pub trait SuccinctTree<T, Label>: Debug { ...@@ -9,7 +9,7 @@ pub trait SuccinctTree<T, Label>: Debug {
fn parent(&self, index: u64) -> Result<u64, NodeError>; fn parent(&self, index: u64) -> Result<u64, NodeError>;
fn first_child(&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 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 child_label(&self, index: u64) -> Result<&Label, NodeError>;
fn labeled_child(&self, index: u64, label: Label) -> Result<u64, NodeError>; fn labeled_child(&self, index: u64, label: Label) -> Result<u64, NodeError>;
......
...@@ -51,13 +51,13 @@ pub struct BPTree<L> { ...@@ -51,13 +51,13 @@ pub struct BPTree<L> {
minmax: MinMax, minmax: MinMax,
} }
impl<L> PartialEq for BPTree<L> { impl<L: PartialEq + Clone> PartialEq for BPTree<L> {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.rankselect.bits() == other.rankselect.bits() 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. /// Checks if a node is a leaf.
/// # Arguments /// # Arguments
/// * `index` The index of the node to check /// * `index` The index of the node to check
...@@ -102,6 +102,7 @@ impl<L> SuccinctTree<BPTree<L>, L> for BPTree<L> { ...@@ -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. /// * `index` The index of the node to get the next sibling of.
/// # Errors /// # Errors
/// * `NotANodeError` If `index` does not reference a node. /// * `NotANodeError` If `index` does not reference a node.
/// * `NoSiblingError` If `index` has no further siblings.
fn next_sibling(&self, index: u64) -> Result<u64, NodeError> { fn next_sibling(&self, index: u64) -> Result<u64, NodeError> {
let parent_a = self.parent(index)?; let parent_a = self.parent(index)?;
let sibling = self.minmax.find_close(index)? + 1; let sibling = self.minmax.find_close(index)? + 1;
...@@ -118,9 +119,13 @@ impl<L> SuccinctTree<BPTree<L>, L> for BPTree<L> { ...@@ -118,9 +119,13 @@ impl<L> SuccinctTree<BPTree<L>, L> for BPTree<L> {
/// * `tree` The IDTree which should be converted /// * `tree` The IDTree which should be converted
/// # Errors /// # Errors
/// * `EmptyTreeError` If `tree` does not contain any nodes. /// * `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 bitvec = if tree.height() > 0 {
let root_id: &NodeId = tree.root_node_id().unwrap(); 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) Self::traverse_id_tree_for_bitvec(tree.get(root_id).unwrap(), &tree)
} else { } else {
return Err(EmptyTreeError); return Err(EmptyTreeError);
...@@ -130,7 +135,7 @@ impl<L> SuccinctTree<BPTree<L>, L> for BPTree<L> { ...@@ -130,7 +135,7 @@ impl<L> SuccinctTree<BPTree<L>, L> for BPTree<L> {
Ok(Self { Ok(Self {
rankselect: RankSelect::new(bitvec.clone(), superblock_size as usize), rankselect: RankSelect::new(bitvec.clone(), superblock_size as usize),
minmax: MinMax::new(bitvec.clone(), 1024), 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> { ...@@ -138,9 +143,13 @@ impl<L> SuccinctTree<BPTree<L>, L> for BPTree<L> {
/// # Arguments /// # Arguments
/// * `index` The index of the node to get the label of /// * `index` The index of the node to get the label of
/// # Errors /// # Errors
/// * `NotANodeError` If `index` does not reference a node.
/// * `NoLabelError` If `index` does not reference a node with a label. /// * `NoLabelError` If `index` does not reference a node with a label.
fn child_label(&self, index: u64) -> Result<&L, NodeError> { 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 /// Returns the child from the specified node with that label
...@@ -148,20 +157,28 @@ impl<L> SuccinctTree<BPTree<L>, L> for BPTree<L> { ...@@ -148,20 +157,28 @@ impl<L> SuccinctTree<BPTree<L>, L> for BPTree<L> {
/// * `index` The index of the node to analyze /// * `index` The index of the node to analyze
/// * `label` The label which a should have /// * `label` The label which a should have
/// # Errors /// # Errors
/// * `NotANodeError` If `index` does not reference a node.
/// * `NoSuchChildError` If there is no child which has this label /// * `NoSuchChildError` If there is no child which has this label
fn labeled_child(&self, index: u64, label: L) -> Result<u64, NodeError> { 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 { fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "BPTree\n {{ bits: {:?} }}", self.rankselect.bits()) write!(f, "BPTree\n {{ bits: {:?} }}", self.rankselect.bits())
} }
} }
impl<L> BPTree<L> { impl<L: PartialEq + Clone> BPTree<L> {
/// Returns whether the index is valid /// Returns whether the index is valid
/// # Arguments /// # Arguments
/// * `index` The index which should be valid /// * `index` The index which should be valid
...@@ -264,7 +281,7 @@ impl<L> BPTree<L> { ...@@ -264,7 +281,7 @@ impl<L> BPTree<L> {
Ok(()) 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(); let mut bitvec = BitVec::new();
bitvec.push(true); bitvec.push(true);
for child in node.children() { for child in node.children() {
...@@ -451,7 +468,7 @@ mod tests { ...@@ -451,7 +468,7 @@ mod tests {
#[test] #[test]
fn traverse_id_tree_for_bitvec() { fn traverse_id_tree_for_bitvec() {
let bitvec = bit_vec!(true, true, true, false, false, true, false, false); 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 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 root_id: NodeId = id_tree.insert(Node::new(0), AsRoot).unwrap();
let child_id = id_tree.insert(Node::new(1), UnderNode(&root_id)).unwrap(); let child_id = id_tree.insert(Node::new(1), UnderNode(&root_id)).unwrap();
...@@ -464,7 +481,7 @@ mod tests { ...@@ -464,7 +481,7 @@ mod tests {
#[test] #[test]
fn from_empty_id_tree() { fn from_empty_id_tree() {
let id_tree: Tree<i32> = TreeBuilder::new().with_node_capacity(5).build(); 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); assert_eq!(bp_tree.unwrap_err(), EmptyTreeError);
} }
...@@ -478,4 +495,11 @@ mod tests { ...@@ -478,4 +495,11 @@ mod tests {
"BPTree\n { bits: bit_vec![true, true, false, true, false, false] }" "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);
}
} }
...@@ -132,7 +132,7 @@ impl<L> SuccinctTree<LOUDSTree<L>, L> for LOUDSTree<L> { ...@@ -132,7 +132,7 @@ impl<L> SuccinctTree<LOUDSTree<L>, L> for LOUDSTree<L> {
/// * `tree` The IDTree which should be converted /// * `tree` The IDTree which should be converted
/// # Errors /// # Errors
/// * `EmptyTreeError` If `tree` does not contain any nodes. /// * `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() { let root = match tree.root_node_id() {
Some(id) => id, Some(id) => id,
None => return Err(EmptyTreeError), None => return Err(EmptyTreeError),
...@@ -396,7 +396,7 @@ mod tests { ...@@ -396,7 +396,7 @@ mod tests {
let child_id = id_tree.insert(Node::new(1), UnderNode(&root_id)).unwrap(); 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(2), UnderNode(&root_id)).unwrap();
id_tree.insert(Node::new(3), UnderNode(&child_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 bitvec = bit_vec![true, true, true, false, true, false, false, false];
let other_tree = LOUDSTree::from_bitvec(bitvec).unwrap(); let other_tree = LOUDSTree::from_bitvec(bitvec).unwrap();
assert_eq!(tree, other_tree) assert_eq!(tree, other_tree)
...@@ -405,7 +405,7 @@ mod tests { ...@@ -405,7 +405,7 @@ mod tests {
#[test] #[test]
fn from_empty_id_tree() { fn from_empty_id_tree() {
let id_tree: Tree<i32> = TreeBuilder::new().with_node_capacity(5).build(); 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); assert_eq!(tree.unwrap_err(), EmptyTreeError);
} }
} }
No preview for this file type
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment