Skip to content
Snippets Groups Projects
Select Git revision
  • 6a968c90d6512ac350d544c7d611ff79bde276db
  • master default protected
  • dan_min_max
  • label_ops
  • benchmarks
  • min_max_fred
  • louds_tree
  • bptree_ops
  • bp_loadsave
  • travis_experiments
10 results

louds_tree.rs

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    louds_tree.rs 14.41 KiB
    // Copyright 2018 David Mehren.
    // Licensed under the MIT license (http://opensource.org/licenses/MIT)
    // This file may not be copied, modified, or distributed
    // except according to those terms.
    
    //! LOUDS succinct tree implementation based on Jacobson (1989) and Arroyuelo et al. (2010)
    //!
    //! Example
    //!
    //! ```
    //! #[macro_use]
    //! extern crate bv;
    //! # extern crate fp_succinct_trees_1;
    //!
    //! # fn main() {
    //! use bv::BitVec;
    //! use bv::Bits;
    //! use fp_succinct_trees_1::common::succinct_tree::SuccinctTree;
    //! use fp_succinct_trees_1::trees::louds_tree::LOUDSTree;
    //!
    //! let bitvec = bit_vec![true, true, false, false];
    //! let tree = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
    //! assert!(tree.is_leaf(3).unwrap());
    //! # }
    //! ```
    
    use bincode::{deserialize, serialize};
    use bio::data_structures::rank_select::RankSelect;
    use bv::{BitVec, Bits};
    use common::errors::{EmptyTreeError, InvalidBitvecError, NodeError};
    use common::succinct_tree::SuccinctTree;
    use failure::{Error, ResultExt};
    use id_tree::Tree;
    use std::fmt;
    use std::fmt::{Debug, Formatter};
    use std::fs;
    use std::fs::File;
    use std::io::Write;
    use std::vec::Vec;
    
    pub struct LOUDSTree<L> {
        rankselect: RankSelect,
        labels: Vec<L>,
    }
    
    impl<L> PartialEq for LOUDSTree<L> {
        fn eq(&self, other: &Self) -> bool {
            self.rankselect.bits() == other.rankselect.bits()
        }
    }
    
    impl<L> Debug for LOUDSTree<L> {
        fn fmt(&self, f: &mut Formatter) -> fmt::Result {
            write!(f, "LOUDSTree\n  {{ bits: {:?} }}", self.rankselect.bits())
        }
    }
    
    impl<L> SuccinctTree<LOUDSTree<L>, L> for LOUDSTree<L> {
        /// Checks if a node is a leaf.
        /// # Arguments
        /// * `index` The index of the node to check
        /// # Errors
        /// * `NotANodeError` If `index` does not reference a node.
        fn is_leaf(&self, index: u64) -> Result<bool, NodeError> {
            if index >= self.rankselect.bits().bit_len()
                || index == 0
                || (!self.rankselect.bits().get_bit(index) && self.rankselect.bits().get_bit(index - 1))
            {
                Err(NodeError::NotANodeError)
            } else {
                Ok(!self.rankselect.bits().get_bit(index))
            }
        }
    
        /// Returns the index of the parent of this node
        /// # Arguments
        /// * `index` The index of the node to get the parent of.
        /// # Errors
        /// * `NotANodeError` If `index` does not reference a node.
        /// * `HasNoParentError` If `index` references the root node.
        fn parent(&self, index: u64) -> Result<u64, NodeError> {
            if index >= self.rankselect.bits().bit_len() || index == 0 {
                Err(NodeError::NotANodeError)
            } else if index == 1 {
                Err(NodeError::RootNodeError)
            } else {
                Ok(self
                    .prev_0(
                        self.rankselect
                            .select_1(self.rankselect.rank_0(index).unwrap())
                            .unwrap(),
                    )
                    .unwrap() + 1)
            }
        }
    
        /// Returns the index of the nodes first child.
        /// # Arguments
        /// * `index` The index of the node to get the first child of.
        /// # Errors
        /// * `NotANodeError` If `index` does not reference a node.
        /// * `NotAParentError` If `index` references a leaf.
        fn first_child(&self, index: u64) -> Result<u64, NodeError> {
            if self.is_leaf(index)? {
                Err(NodeError::NotAParentError)
            } else {
                Ok(self.child(index, 1).unwrap())
            }
        }
    
        /// Returns the index of the next sibling
        /// # Arguments
        /// * `index` The index of the node to get the next sibling of.
        /// # Errors
        /// * `NotANodeError` If `index` does not reference a node.
        fn next_sibling(&self, index: u64) -> Result<u64, NodeError> {
            let parent_a = self.parent(index)?;
            let sibling = self
                .rankselect
                .select_0(self.rankselect.rank_0(index - 1).unwrap() + 1)
                .unwrap() + 1;
            let parent_b = self.parent(sibling)?;
            if parent_a == parent_b {
                Ok(sibling)
            } else {
                Err(NodeError::NoSiblingError)
            }
        }
    
        /// Constructs a LOUDSTree from a IDTree
        /// # Arguments
        /// * `tree` The IDTree which should be converted
        /// # Errors
        /// * `EmptyTreeError` If `tree` does not contain any nodes.
        fn from_id_tree(tree: Tree<L>) -> Result<Self, EmptyTreeError> {
            let root = match tree.root_node_id() {
                Some(id) => id,
                None => return Err(EmptyTreeError),
            };
            let mut bitvec: BitVec<u8> = BitVec::new_fill(true, 1);
            for node in tree.traverse_level_order(root).unwrap() {
                let child_count = node.children().len();
                for _ in 0..child_count {
                    bitvec.push(true);
                }
                bitvec.push(false);
            }
            Ok(Self::from_bitvec(bitvec).unwrap())
        }
    
        /// Returns the label for the edge between the parent and the node
        /// # Arguments
        /// * `index` The index of the node to get the label of
        /// # Errors
        /// * `NotANodeError` If `index` does not reference a node.
        fn child_label(&self, index: u64) -> Result<&L, NodeError> {
            unimplemented!();
        }
    
        fn labeled_child(&self, index: u64, label: L) -> Result<u64, NodeError> {
            unimplemented!();
        }
    }
    
    impl<L> LOUDSTree<L> {
        fn prev_0(&self, index: u64) -> Option<u64> {
            self.rankselect.select_0(self.rankselect.rank_0(index)?)
        }
    
        fn next_0(&self, index: u64) -> Option<u64> {
            self.rankselect.select_0(self.rankselect.rank_0(index)? + 1)
        }
    
        pub fn child(&self, index: u64, n: u64) -> Option<u64> {
            Some(
                self.rankselect
                    .select_0(self.rankselect.rank_1(index)? + n - 2)? + 1,
            )
        }
        pub fn degree(&self, index: u64) -> Result<u64, NodeError> {
            if self.is_leaf(index)? {
                Ok(0)
            } else {
                // We could just unwrap() here, because invalid indices have been dealt with in is_leaf()
                Ok(self.next_0(index).ok_or(NodeError::NotANodeError)? - index)
            }
        }
        pub fn child_rank(&self, index: u64) -> Option<u64> {
            let y = self
                .rankselect
                .select_1(self.rankselect.rank_0(index - 1)?)?;
            Some(y - self.prev_0(y)?)
        }
        pub fn from_bitvec(bitvec: BitVec<u8>) -> Result<Self, InvalidBitvecError> {
            if !Self::is_valid(&bitvec as &BitVec<u8>) {
                return Err(InvalidBitvecError);
            }
            let superblock_size = Self::calc_superblock_size(bitvec.len());
            Ok(Self {
                labels: Vec::with_capacity(bitvec.len() as usize),
                rankselect: RankSelect::new(bitvec, superblock_size as usize),
            })
        }
    
        pub fn from_file(path: String) -> Result<Self, Error> {
            let file = fs::read(path).context("Could not read saved tree.")?;
            let rankselect: RankSelect = deserialize(&file).context("Error while deserializing tree.")?;
            Ok(Self {
                labels: Vec::with_capacity(rankselect.bits().len() as usize),
                rankselect: rankselect,
            })
        }
    
        pub fn save_to(&self, path: String) -> Result<(), Error> {
            let encoded = serialize(&self.rankselect).context("Error while serializing tree.")?;
            let mut file = File::create(path).context("Could not save tree.")?;
            file.write_all(&encoded)?;
            Ok(())
        }
    }
    
    #[cfg(test)]
    mod tests {
        use super::*;
        use id_tree::InsertBehavior::{AsRoot, UnderNode};
        use id_tree::{Node, NodeId, TreeBuilder};
    
        #[test]
        fn new_from_bitvec() {
            let bitvec = bit_vec![true, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            assert_eq!(
                *tree.rankselect.bits(),
                bitvec,
                "BPTree seems to somehow change the bitvector it was created with."
            );
        }
    
        #[test]
        fn new_from_bitvec_invalid() {
            let bitvec = bit_vec![true, true];
            let tree: Result<LOUDSTree<String>, InvalidBitvecError> = LOUDSTree::from_bitvec(bitvec);
            assert_eq!(tree.unwrap_err(), InvalidBitvecError);
        }
    
        #[test]
        fn save_load() {
            let bitvec =
                bit_vec![true, true, true, true, false, true, false, true, false, false, false, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            tree.save_to("testdata/loudstree.testdata".to_string())
                .unwrap();
            let result: LOUDSTree<String> =
                LOUDSTree::from_file("testdata/loudstree.testdata".to_string()).unwrap();
            assert_eq!(
                tree, result,
                "The loaded tree is not equal to the original one."
            );
        }
    
        #[test]
        #[should_panic(expected = "Error while deserializing tree.")]
        fn load_invalid() {
            let _tree: LOUDSTree<String> =
                LOUDSTree::from_file("testdata/loudstree_invalid.testdata".to_string()).unwrap();
        }
    
        #[test]
        fn is_leaf() {
            let bitvec = bit_vec![true, true, false, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            assert!(tree.is_leaf(3).unwrap());
        }
    
        #[test]
        fn is_no_leaf() {
            let bitvec = bit_vec![true, true, false, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            assert!(!tree.is_leaf(1).unwrap());
        }
    
        #[test]
        fn is_leaf_wrong_index() {
            let bitvec = bit_vec![true, true, false, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            assert_eq!(tree.is_leaf(2).unwrap_err(), NodeError::NotANodeError);
        }
    
        #[test]
        fn is_leaf_wrong_index2() {
            let bitvec = bit_vec![true, true, false, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            assert_eq!(tree.is_leaf(4).unwrap_err(), NodeError::NotANodeError);
        }
    
        #[test]
        fn first_child() {
            let bitvec = bit_vec![true, true, false, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            assert_eq!(tree.first_child(1).unwrap(), 3);
        }
    
        #[test]
        fn first_child_no_parent() {
            let bitvec = bit_vec![true, true, false, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            assert_eq!(tree.first_child(3).unwrap_err(), NodeError::NotAParentError);
        }
    
        #[test]
        fn parent() {
            let bitvec = bit_vec![true, true, false, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            assert_eq!(tree.parent(3).unwrap(), 1)
        }
    
        #[test]
        fn parent_root_node() {
            let bitvec = bit_vec![true, true, false, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            assert_eq!(tree.parent(1).unwrap_err(), NodeError::RootNodeError)
        }
    
        #[test]
        fn parent_no_node() {
            let bitvec = bit_vec![true, true, false, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            assert_eq!(tree.parent(0).unwrap_err(), NodeError::NotANodeError)
        }
    
        #[test]
        fn next_sibling() {
            let bitvec =
                bit_vec![true, true, true, true, false, true, false, true, false, false, false, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            assert_eq!(tree.next_sibling(5).unwrap(), 7);
            assert_eq!(tree.next_sibling(7).unwrap(), 9);
        }
    
        #[test]
        fn no_next_sibling() {
            let bitvec =
                bit_vec![true, true, true, true, false, true, false, true, false, false, false, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            assert_eq!(
                tree.next_sibling(10).unwrap_err(),
                NodeError::NoSiblingError
            );
        }
    
        #[test]
        fn degree() {
            let bitvec =
                bit_vec![true, true, true, true, false, true, false, true, false, false, false, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            assert_eq!(tree.degree(1).unwrap(), 3);
            assert_eq!(tree.degree(5).unwrap(), 1);
            assert_eq!(tree.degree(9).unwrap(), 0);
        }
    
        #[test]
        fn child_rank() {
            let bitvec =
                bit_vec![true, true, true, true, false, true, false, true, false, false, false, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            assert_eq!(tree.child_rank(9).unwrap(), 2);
            assert_eq!(tree.child_rank(7).unwrap(), 1);
            assert_eq!(tree.child_rank(5).unwrap(), 0);
        }
    
        #[test]
        fn print() {
            let bitvec =
                bit_vec![true, true, true, true, false, true, false, true, false, false, false, false];
            let tree: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec.clone()).unwrap();
            let str = format!("{:?}", tree);
            assert_eq!(str, "LOUDSTree\n  { bits: bit_vec![true, true, true, true, false, true, false, true, false, false, false, false] }")
        }
    
        #[test]
        fn partial_eq() {
            let bitvec_a =
                bit_vec![true, true, true, true, false, true, false, true, false, false, false, false];
            let bitvec_b = bit_vec![true, true, false, false];
            let tree_a: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec_a.clone()).unwrap();
            let tree_b: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec_a.clone()).unwrap();
            let tree_c: LOUDSTree<String> = LOUDSTree::from_bitvec(bitvec_b.clone()).unwrap();
            assert_eq!(tree_a, tree_b);
            assert_ne!(tree_a, tree_c)
        }
    
        #[test]
        fn from_id_tree() {
            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();
            id_tree.insert(Node::new(2), UnderNode(&root_id)).unwrap();
            id_tree.insert(Node::new(3), UnderNode(&child_id)).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)
        }
    
        #[test]
        fn from_empty_id_tree() {
            let id_tree: Tree<i32> = TreeBuilder::new().with_node_capacity(5).build();
            let tree: Result<LOUDSTree<i32>, EmptyTreeError> = LOUDSTree::from_id_tree(id_tree);
            assert_eq!(tree.unwrap_err(), EmptyTreeError);
        }
    }