Skip to content

Commit

Permalink
Merge pull request #332 from simongog/fix331
Browse files Browse the repository at this point in the history
Fixing issue #331
  • Loading branch information
simongog authored Jun 13, 2016
2 parents dd81dc1 + 0c2fac2 commit 7a7bec4
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 50 deletions.
22 changes: 11 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ matrix:
- cmake
- g++-5

- env: MYCC="clang-3.7" MYCXX="clang++-3.7" STDLIB=libc++
os: linux
addons: &clang37
apt:
sources:
- kalakris-cmake
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
packages:
- cmake
- clang-3.7
# - env: MYCC="clang-3.7" MYCXX="clang++-3.7" STDLIB=libc++
# os: linux
# addons: &clang37
# apt:
# sources:
# - kalakris-cmake
# - ubuntu-toolchain-r-test
# - llvm-toolchain-precise-3.7
# packages:
# - cmake
# - clang-3.7

- env: MYCC="clang" MYCXX="clang++" STDLIB=libc++
os: osx
Expand Down
114 changes: 75 additions & 39 deletions include/sdsl/wt_pc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ class wt_pc
select_0_type m_bv_select0;
tree_strat_type m_tree;

void copy(const wt_pc& wt) {
void copy(const wt_pc& wt)
{
m_size = wt.m_size;
m_sigma = wt.m_sigma;
m_bv = wt.m_bv;
Expand All @@ -107,7 +108,8 @@ class wt_pc

// insert a character into the wavelet tree, see construct method
void insert_char(value_type old_chr, std::vector<uint64_t>& bv_node_pos,
size_type times, bit_vector& bv) {
size_type times, bit_vector& bv)
{
uint64_t p = m_tree.bit_path(old_chr);
uint32_t path_len = p>>56;
node_type v = m_tree.root();
Expand All @@ -123,7 +125,8 @@ class wt_pc


// calculates the tree shape returns the size of the WT bit vector
size_type construct_tree_shape(const std::vector<size_type>& C) {
size_type construct_tree_shape(const std::vector<size_type>& C)
{
// vector for node of the tree
std::vector<pc_node> temp_nodes; //(2*m_sigma-1);
shape_type::construct_tree(C, temp_nodes);
Expand All @@ -135,7 +138,8 @@ class wt_pc
return bv_size;
}

void construct_init_rank_select() {
void construct_init_rank_select()
{
util::init_support(m_bv_rank, &m_bv);
util::init_support(m_bv_select0, &m_bv);
util::init_support(m_bv_select1, &m_bv);
Expand All @@ -146,7 +150,8 @@ class wt_pc
_interval_symbols(size_type i, size_type j, size_type& k,
std::vector<value_type>& cs,
std::vector<size_type>& rank_c_i,
std::vector<size_type>& rank_c_j, node_type v) const {
std::vector<size_type>& rank_c_j, node_type v) const
{
// invariant: j>i
size_type i_new = (m_bv_rank(m_tree.bv_pos(v) + i)
- m_tree.bv_pos_rank(v));
Expand Down Expand Up @@ -194,7 +199,8 @@ class wt_pc
* \f$ \Order{n\log|\Sigma|}\f$, where \f$n=size\f$
*/
wt_pc(int_vector_buffer<tree_strat_type::int_width>& input_buf,
size_type size):m_size(size) {
size_type size):m_size(size)
{
if (0 == m_size)
return;
// O(n + |\Sigma|\log|\Sigma|) algorithm for calculating node sizes
Expand Down Expand Up @@ -250,20 +256,23 @@ class wt_pc
//! Copy constructor
wt_pc(const wt_pc& wt) { copy(wt); }

wt_pc(wt_pc&& wt) {
wt_pc(wt_pc&& wt)
{
*this = std::move(wt);
}

//! Assignment operator
wt_pc& operator=(const wt_pc& wt) {
wt_pc& operator=(const wt_pc& wt)
{
if (this != &wt) {
copy(wt);
}
return *this;
}

//! Assignment operator
wt_pc& operator=(wt_pc&& wt) {
wt_pc& operator=(wt_pc&& wt)
{
if (this != &wt) {
m_size = wt.m_size;
m_sigma = wt.m_sigma;
Expand All @@ -281,7 +290,8 @@ class wt_pc


//! Swap operator
void swap(wt_pc& wt) {
void swap(wt_pc& wt)
{
if (this != &wt) {
std::swap(m_size, wt.m_size);
std::swap(m_sigma, wt.m_sigma);
Expand Down Expand Up @@ -314,7 +324,8 @@ class wt_pc
* \par Precondition
* \f$ i < size() \f$
*/
value_type operator[](size_type i)const {
value_type operator[](size_type i)const
{
assert(i < size());
// which stores how many of the next symbols are equal
// with the current char
Expand Down Expand Up @@ -346,7 +357,8 @@ class wt_pc
* \par Precondition
* \f$ i \leq size() \f$
*/
size_type rank(size_type i, value_type c)const {
size_type rank(size_type i, value_type c)const
{
assert(i <= size());
if (!m_tree.is_valid(m_tree.c_to_leaf(c))) {
return 0; // if `c` was not in the text
Expand Down Expand Up @@ -382,7 +394,8 @@ class wt_pc
* \f$ i < size() \f$
*/
std::pair<size_type, value_type>
inverse_select(size_type i)const {
inverse_select(size_type i)const
{
assert(i < size());
node_type v = m_tree.root();
while (!m_tree.is_leaf(v)) { // while not a leaf
Expand Down Expand Up @@ -411,7 +424,8 @@ class wt_pc
* \par Precondition
* \f$ 1 \leq i \leq rank(size(), c) \f$
*/
size_type select(size_type i, value_type c)const {
size_type select(size_type i, value_type c)const
{
assert(1 <= i and i <= rank(size(), c));
node_type v = m_tree.c_to_leaf(c);
if (!m_tree.is_valid(v)) { // if c was not in the text
Expand Down Expand Up @@ -466,7 +480,8 @@ class wt_pc
void interval_symbols(size_type i, size_type j, size_type& k,
std::vector<value_type>& cs,
std::vector<size_type>& rank_c_i,
std::vector<size_type>& rank_c_j) const {
std::vector<size_type>& rank_c_j) const
{
assert(i <= j and j <= size());
if (i==j) {
k = 0;
Expand Down Expand Up @@ -522,7 +537,8 @@ class wt_pc
*/
template<class t_ret_type = std::tuple<size_type, size_type, size_type>>
typename std::enable_if<shape_type::lex_ordered, t_ret_type>::type
lex_count(size_type i, size_type j, value_type c) const {
lex_count(size_type i, size_type j, value_type c) const
{
assert(i <= j and j <= size());
if (1==m_sigma) {
value_type _c = m_tree.bv_pos_rank(m_tree.root());
Expand Down Expand Up @@ -583,7 +599,8 @@ class wt_pc
*/
template<class t_ret_type = std::tuple<size_type, size_type>>
typename std::enable_if<shape_type::lex_ordered, t_ret_type>::type
lex_smaller_count(size_type i, value_type c)const {
lex_smaller_count(size_type i, value_type c)const
{
assert(i <= size());
if (1==m_sigma) {
value_type _c = m_tree.bv_pos_rank(m_tree.root());
Expand Down Expand Up @@ -624,18 +641,21 @@ class wt_pc
}

//! Returns a const_iterator to the first element.
const_iterator begin()const {
const_iterator begin()const
{
return const_iterator(this, 0);
}

//! Returns a const_iterator to the element after the last element.
const_iterator end()const {
const_iterator end()const
{
return const_iterator(this, size());
}

//! Serializes the data structure into the given ostream
size_type serialize(std::ostream& out, structure_tree_node* v=nullptr,
std::string name="") const {
std::string name="") const
{
structure_tree_node* child = structure_tree::add_child(
v, name, util::class_name(*this));
size_type written_bytes = 0;
Expand All @@ -651,7 +671,8 @@ class wt_pc
}

//! Loads the data structure from the given istream.
void load(std::istream& in) {
void load(std::istream& in)
{
read_member(m_size, in);
read_member(m_sigma, in);
m_bv.load(in);
Expand All @@ -668,7 +689,8 @@ class wt_pc

//! Random access container to sequence of node v
auto seq(const node_type& v) const -> random_access_container<std::function<value_type(size_type)>> {
return random_access_container<std::function<value_type(size_type)>>([&v, this](size_type i) {
return random_access_container<std::function<value_type(size_type)>>([&v, this](size_type i)
{
node_type vv = v;
while (!is_leaf(vv)) {
auto vs = expand(vv);
Expand All @@ -682,22 +704,26 @@ class wt_pc
}

//! Checks if the node is a leaf node
bool is_leaf(const node_type& v) const {
bool is_leaf(const node_type& v) const
{
return m_tree.is_leaf(v);
}

//! Symbol for a leaf
value_type sym(const node_type& v) const {
value_type sym(const node_type& v) const
{
return m_tree.bv_pos_rank(v);
}

//! Indicates if node v is empty
bool empty(const node_type& v) const {
bool empty(const node_type& v) const
{
return size(v)==0;
}

//! Return the size of node v
auto size(const node_type& v) const -> decltype(m_tree.size(v)) {
auto size(const node_type& v) const -> decltype(m_tree.size(v))
{
if (is_leaf(v)) {
if (v == root())
return size();
Expand All @@ -715,7 +741,8 @@ class wt_pc
}

//! Returns the root node
node_type root() const {
node_type root() const
{
return m_tree.root();
}

Expand All @@ -725,8 +752,9 @@ class wt_pc
* \pre !is_leaf(v)
*/
std::array<node_type, 2>
expand(const node_type& v) const {
return {m_tree.child(v,0), m_tree.child(v,1)};
expand(const node_type& v) const
{
return {{m_tree.child(v,0), m_tree.child(v,1)}};
}

//! Returns for each range its left and right child ranges
Expand All @@ -741,7 +769,8 @@ class wt_pc
*/
std::array<range_vec_type, 2>
expand(const node_type& v,
const range_vec_type& ranges) const {
const range_vec_type& ranges) const
{
auto ranges_copy = ranges;
return expand(v, std::move(ranges_copy));
}
Expand All @@ -758,7 +787,8 @@ class wt_pc
*/
std::array<range_vec_type, 2>
expand(const node_type& v,
range_vec_type&& ranges) const {
range_vec_type&& ranges) const
{
auto v_sp_rank = m_tree.bv_pos_rank(v);
range_vec_type res(ranges.size());
size_t i = 0;
Expand Down Expand Up @@ -788,7 +818,8 @@ class wt_pc
* \pre !is_leaf(v) and s>=v_s and e<=v_e
*/
std::array<range_type, 2>
expand(const node_type& v, const range_type& r) const {
expand(const node_type& v, const range_type& r) const
{
auto v_sp_rank = m_tree.bv_pos_rank(v);
auto sp_rank = m_bv_rank(m_tree.bv_pos(v) + r[0]);
auto right_size = m_bv_rank(m_tree.bv_pos(v) + r[1] + 1)
Expand All @@ -798,14 +829,15 @@ class wt_pc
auto right_sp = sp_rank - v_sp_rank;
auto left_sp = r[0] - right_sp;

return {{{left_sp, left_sp + left_size - 1},
{right_sp, right_sp + right_size - 1}
return {{{{left_sp, left_sp + left_size - 1}},
{{right_sp, right_sp + right_size - 1}}
}
};
}

//! return the path to the leaf for a given symbol
std::pair<uint64_t,uint64_t> path(value_type c) const {
std::pair<uint64_t,uint64_t> path(value_type c) const
{
uint64_t path = m_tree.bit_path(c);
uint64_t path_len = path >> 56;
// reverse the path till we fix the ordering
Expand All @@ -820,7 +852,8 @@ class wt_pc
* a valid answer was found (true) or no valid answer (false)
* could be found. The second element contains the found symbol.
*/
std::pair<bool, value_type> symbol_gte(value_type c) const {
std::pair<bool, value_type> symbol_gte(value_type c) const
{
return m_tree.symbol_gte(c);
}

Expand All @@ -830,19 +863,22 @@ class wt_pc
* a valid answer was found (true) or no valid answer (false)
* could be found. The second element contains the found symbol.
*/
std::pair<bool, value_type> symbol_lte(value_type c) const {
std::pair<bool, value_type> symbol_lte(value_type c) const
{
return m_tree.symbol_lte(c);
}

private:

//! Iterator to the begin of the bitvector of inner node v
auto begin(const node_type& v) const -> decltype(m_bv.begin() + m_tree.bv_pos(v)) {
auto begin(const node_type& v) const -> decltype(m_bv.begin() + m_tree.bv_pos(v))
{
return m_bv.begin() + m_tree.bv_pos(v);
}

//! Iterator to the begin of the bitvector of inner node v
auto end(const node_type& v) const -> decltype(m_bv.begin() + m_tree.bv_pos(v) + m_tree.size(v)) {
auto end(const node_type& v) const -> decltype(m_bv.begin() + m_tree.bv_pos(v) + m_tree.size(v))
{
return m_bv.begin() + m_tree.bv_pos(v) + m_tree.size(v);
}
};
Expand Down

0 comments on commit 7a7bec4

Please sign in to comment.