Skip to content
Snippets Groups Projects
Verified Commit d4575dbf authored by David Mehren's avatar David Mehren
Browse files

[LOUDSTree] Implement child_label

parent f8941282
No related branches found
No related tags found
No related merge requests found
...@@ -43,19 +43,19 @@ pub struct LOUDSTree<L> { ...@@ -43,19 +43,19 @@ pub struct LOUDSTree<L> {
labels: Vec<L>, labels: Vec<L>,
} }
impl<L: PartialEq + Clone> PartialEq for LOUDSTree<L> { impl<L: PartialEq + Clone + Debug> PartialEq for LOUDSTree<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: PartialEq + Clone> Debug for LOUDSTree<L> { impl<L: PartialEq + Clone + Debug> Debug for LOUDSTree<L> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result { fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "LOUDSTree\n {{ bits: {:?} }}", self.rankselect.bits()) write!(f, "LOUDSTree\n {{ bits: {:?} }}", self.rankselect.bits())
} }
} }
impl<L: PartialEq + Clone> SuccinctTree<LOUDSTree<L>, L> for LOUDSTree<L> { impl<L: PartialEq + Clone + Debug> SuccinctTree<LOUDSTree<L>, L> for LOUDSTree<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
...@@ -147,7 +147,7 @@ impl<L: PartialEq + Clone> SuccinctTree<LOUDSTree<L>, L> for LOUDSTree<L> { ...@@ -147,7 +147,7 @@ impl<L: PartialEq + Clone> SuccinctTree<LOUDSTree<L>, L> for LOUDSTree<L> {
} }
let mut l_tree = Self::from_bitvec(bitvec).unwrap(); let mut l_tree = Self::from_bitvec(bitvec).unwrap();
for node in tree.traverse_pre_order(root).unwrap() { for node in tree.traverse_level_order(root).unwrap() {
l_tree.labels.push((*node.data()).clone()); l_tree.labels.push((*node.data()).clone());
} }
Ok(l_tree) Ok(l_tree)
...@@ -161,20 +161,40 @@ impl<L: PartialEq + Clone> SuccinctTree<LOUDSTree<L>, L> for LOUDSTree<L> { ...@@ -161,20 +161,40 @@ impl<L: PartialEq + Clone> SuccinctTree<LOUDSTree<L>, L> for LOUDSTree<L> {
fn child_label(&self, index: u64) -> Result<&L, NodeError> { fn child_label(&self, index: u64) -> Result<&L, NodeError> {
// child label(x) = // child label(x) =
//L[rank ( (parent(x)) + child rank(x) − 1] //L[rank ( (parent(x)) + child rank(x) − 1]
let parent = self.parent(index)?; let parent =
let child_rank = self.child_rank(index).ok_or(NodeError::NotANodeError)?; if index != 1 { self.parent(index)? } else { 0 };
let child_rank = if index == 1 || self.degree(parent)? == 1 {
0
} else {
self.child_rank(index)
.ok_or(NodeError::NotANodeError)
.unwrap()
};
let parent_rank = self.rankselect.rank_1(parent).unwrap();
Ok(self Ok(self
.labels .labels
.get((parent + child_rank - 1) as usize) .get((parent_rank + child_rank - 1) as usize)
.ok_or(NodeError::NoLabelError)?) .ok_or(NodeError::NoLabelError)?)
} }
fn labeled_child(&self, index: u64, label: L) -> Result<u64, NodeError> { fn labeled_child(&self, index: u64, label: L) -> Result<u64, NodeError> {
unimplemented!(); println!("Foobar");
let left_bound = self
.rankselect
.rank_0(index)
.ok_or(NodeError::NotANodeError)?;
let right_bound = left_bound + self.degree(index)? - 1;
for i in left_bound..right_bound {
let item = self.labels.get(i as usize).unwrap();
if label == *item {
return Ok(i);
}
}
Err(NodeError::NoSuchChildError)
} }
} }
impl<L: PartialEq + Clone> LOUDSTree<L> { impl<L: PartialEq + Clone + Debug> LOUDSTree<L> {
fn prev_0(&self, index: u64) -> Option<u64> { fn prev_0(&self, index: u64) -> Option<u64> {
self.rankselect.select_0(self.rankselect.rank_0(index)?) self.rankselect.select_0(self.rankselect.rank_0(index)?)
} }
...@@ -198,16 +218,21 @@ impl<L: PartialEq + Clone> LOUDSTree<L> { ...@@ -198,16 +218,21 @@ impl<L: PartialEq + Clone> LOUDSTree<L> {
} }
} }
pub fn child_rank(&self, index: u64) -> Option<u64> { pub fn child_rank(&self, index: u64) -> Option<u64> {
if index <= 1 {
return Some(0);
}
let y = self let y = self
.rankselect .rankselect
.select_1(self.rankselect.rank_0(index - 1)?)?; .select_1(self.rankselect.rank_0(index - 1)?)?;
Some(y - self.prev_0(y)?) Some(y - self.prev_0(y)?)
} }
pub fn from_bitvec(bitvec: BitVec<u8>) -> Result<Self, InvalidBitvecError> { pub fn from_bitvec(bitvec: BitVec<u8>) -> Result<Self, InvalidBitvecError> {
if !Self::is_valid(&bitvec as &BitVec<u8>) { if !Self::is_valid(&bitvec as &BitVec<u8>) {
return Err(InvalidBitvecError); return Err(InvalidBitvecError);
} }
let superblock_size = Self::calc_superblock_size(bitvec.len()); let superblock_size = Self::calc_superblock_size(bitvec.len());
Ok(Self { Ok(Self {
labels: Vec::with_capacity(bitvec.len() as usize), labels: Vec::with_capacity(bitvec.len() as usize),
rankselect: RankSelect::new(bitvec, superblock_size as usize), rankselect: RankSelect::new(bitvec, superblock_size as usize),
...@@ -378,6 +403,7 @@ mod tests { ...@@ -378,6 +403,7 @@ mod tests {
assert_eq!(tree.child_rank(9).unwrap(), 2); assert_eq!(tree.child_rank(9).unwrap(), 2);
assert_eq!(tree.child_rank(7).unwrap(), 1); assert_eq!(tree.child_rank(7).unwrap(), 1);
assert_eq!(tree.child_rank(5).unwrap(), 0); assert_eq!(tree.child_rank(5).unwrap(), 0);
assert_eq!(tree.child_rank(1).unwrap(), 0);
} }
#[test] #[test]
...@@ -409,6 +435,7 @@ mod tests { ...@@ -409,6 +435,7 @@ mod tests {
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<i32> = LOUDSTree::from_id_tree(id_tree).unwrap(); let tree: LOUDSTree<i32> = LOUDSTree::from_id_tree(id_tree).unwrap();
tree.labeled_child(0, 2);
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)
...@@ -420,4 +447,32 @@ mod tests { ...@@ -420,4 +447,32 @@ mod tests {
let tree: Result<LOUDSTree<String>, EmptyTreeError> = LOUDSTree::from_id_tree(id_tree); let tree: Result<LOUDSTree<String>, EmptyTreeError> = LOUDSTree::from_id_tree(id_tree);
assert_eq!(tree.unwrap_err(), EmptyTreeError); assert_eq!(tree.unwrap_err(), EmptyTreeError);
} }
#[test]
fn child_label() {
let mut id_tree: Tree<String> = TreeBuilder::new().with_node_capacity(5).build();
let root_id: NodeId = id_tree
.insert(Node::new(String::from("root")), AsRoot)
.unwrap();
let child_id = id_tree
.insert(
Node::new(String::from("first_root_child")),
UnderNode(&root_id),
)
.unwrap();
id_tree
.insert(Node::new(String::from("leaf")), UnderNode(&child_id))
.unwrap();
id_tree
.insert(
Node::new(String::from("second_root_child")),
UnderNode(&root_id),
)
.unwrap();
let bp_tree = LOUDSTree::from_id_tree(id_tree).unwrap();
assert_eq!(*bp_tree.child_label(1).unwrap(), "root");
assert_eq!(*bp_tree.child_label(4).unwrap(), "first_root_child");
assert_eq!(*bp_tree.child_label(6).unwrap(), "second_root_child");
assert_eq!(*bp_tree.child_label(7).unwrap(), "leaf");
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment