diff --git a/include/sdsl/wt_int.hpp b/include/sdsl/wt_int.hpp index 33911b8c9..db94c49a7 100644 --- a/include/sdsl/wt_int.hpp +++ b/include/sdsl/wt_int.hpp @@ -166,6 +166,7 @@ class wt_int init_buffers(m_max_level); }; + //! Semi-external constructor /*! \param buf File buffer of the int_vector for which the wt_int should be build. * \param size Size of the prefix of v, which should be indexed. @@ -815,6 +816,40 @@ class wt_int return node_type(0, m_size, 0, 0); } + bool node_access(const node_type & v, size_type i) const { + size_type v_sp_pos = v.offset; + return m_tree[v_sp_pos + i]; + } + + size_type + node_rank1(const node_type & v, size_type i) const { + // Get starting position rank + size_type v_sp_pos = v.offset; + size_type v_sp_rank = m_tree_rank(v_sp_pos); + // TODO: BOUND CHECK: get node size by getting parents left and right children start positions (if any) + return m_tree_rank(v_sp_pos + i) - v_sp_rank; + } + + size_type node_rank0(const node_type & v, size_type i) const { + return i - node_rank1(v, i); + } + + size_type node_select1(const node_type &v, size_type i) const { + size_type v_sp_pos = v.offset; + size_type v_sp_rank1 = m_tree_rank(v_sp_pos); + // TODO: BOUND CHECK: get node size by getting parents left and right children start positions (if any) + return m_tree_select1(i + v_sp_rank1) - v_sp_pos; + } + + size_type node_select0(const node_type &v, size_type i) const { + size_type v_sp_pos = v.offset; + size_type v_sp_rank0 = v_sp_pos - m_tree_rank(v_sp_pos); + // TODO: BOUND CHECK: get node size by getting parents left and right children start positions (if any) + return m_tree_select0(i + v_sp_rank0) - v_sp_pos; + } + + + //! Returns the two child nodes of an inner node /*! \param v An inner node of a wavelet tree. * \return Return an array of nodes (left child, right child). diff --git a/include/sdsl/wt_pc.hpp b/include/sdsl/wt_pc.hpp index 9d8fb1309..7b8e49ed0 100644 --- a/include/sdsl/wt_pc.hpp +++ b/include/sdsl/wt_pc.hpp @@ -807,6 +807,33 @@ class wt_pc return {ranges, std::move(res)}; } + size_type + node_rank1(const node_type & v, size_type i) const { + // Get starting position rank + size_type v_sp_pos = m_tree.bv_pos(v); + size_type v_sp_rank = m_tree.bv_pos_rank(v); + // TODO: BOUND CHECK: get node size by getting parents left and right children start positions (if any) + return m_bv_rank(v_sp_pos + i) - v_sp_rank; + } + + size_type node_rank0(const node_type & v, size_type i) const { + return i - node_rank1(v, i); + } + + size_type node_select1(const node_type &v, size_type i) const { + auto v_sp_pos = m_tree.bv_pos(v); + auto v_sp_rank1 = m_tree.bv_pos_rank(v); + // TODO: BOUND CHECK: get node size by getting parents left and right children start positions (if any) + return m_bv_select1(i + v_sp_rank1) - v_sp_pos; + } + + size_type node_select0(const node_type &v, size_type i) const { + auto v_sp_pos = m_tree.bv_pos(v); + auto v_sp_rank0 = v_sp_pos - m_tree.bv_pos_rank(v); + // TODO: BOUND CHECK: get node size by getting parents left and right children start positions (if any) + return m_bv_select0(i + v_sp_rank0) - v_sp_pos; + } + //! Returns for a range its left and right child ranges /*! \param v An inner node of an wavelet tree. * \param r A ranges [s,e], such that [s,e] is