SDSL: Succinct Data Structure Library
A C++ template library for succinct data structures
 All Classes Namespaces Files Functions Variables Typedefs Friends
sdsl/include/sdsl/rank_support_v.hpp
Go to the documentation of this file.
00001 /* sdsl - succinct data structures library
00002     Copyright (C) 2008 Simon Gog
00003 
00004     This program is free software: you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation, either version 3 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program.  If not, see http://www.gnu.org/licenses/ .
00016 */
00021 #ifndef INCLUDED_SDSL_RANK_SUPPORT_V
00022 #define INCLUDED_SDSL_RANK_SUPPORT_V
00023 
00024 #include "rank_support.hpp"
00025 
00027 namespace sdsl
00028 {
00029 
00030 template<uint8_t bit_pattern, uint8_t pattern_len>
00031 struct rank_support_v_trait {
00032     typedef rank_support::size_type     size_type;
00033 
00034     static size_type args_in_the_word(uint64_t w, uint64_t& carry) {
00035         return 0;
00036     }
00037 
00038     static uint32_t word_rank(const uint64_t* data, size_type idx) {
00039         return 0;
00040     }
00041 
00042     static uint32_t full_word_rank(const uint64_t* data, size_type idx) {
00043         return 0;
00044     }
00045 
00046     static uint64_t init_carry() {
00047         return 0;
00048     }
00049 };
00050 
00051 template<>
00052 struct rank_support_v_trait<0,1> {
00053     typedef rank_support::size_type     size_type;
00054 
00055     static size_type args_in_the_word(uint64_t w, uint64_t&) {
00056         return bit_magic::b1Cnt(~w);
00057     }
00058 
00059     static uint32_t word_rank(const uint64_t* data, size_type idx) {
00060         return  bit_magic::b1Cnt((~*(data+(idx>>6))) & bit_magic::Li1Mask[idx&0x3F]);
00061     }
00062 
00063     static uint32_t full_word_rank(const uint64_t* data, size_type idx) {
00064         return  bit_magic::b1Cnt((~*(data+(idx>>6))));
00065     }
00066 
00067     static uint64_t init_carry() {
00068         return 0;
00069     }
00070 };
00071 
00072 template<>
00073 struct rank_support_v_trait<1,1> {
00074     typedef rank_support::size_type     size_type;
00075 
00076     static size_type args_in_the_word(uint64_t w, uint64_t&) {
00077         return bit_magic::b1Cnt(w);
00078     }
00079 
00080     static uint32_t word_rank(const uint64_t* data, size_type idx) {
00081         return  bit_magic::b1Cnt(*(data+(idx>>6)) & bit_magic::Li1Mask[idx&0x3F]);
00082     }
00083 
00084     static uint32_t full_word_rank(const uint64_t* data, size_type idx) {
00085         return  bit_magic::b1Cnt(*(data+(idx>>6)));
00086     }
00087 
00088     static uint64_t init_carry() {
00089         return 0;
00090     }
00091 };
00092 
00093 template<>
00094 struct rank_support_v_trait<10,2> {
00095     typedef rank_support::size_type     size_type;
00096 
00097     static size_type args_in_the_word(uint64_t w, uint64_t& carry) {
00098         return bit_magic::b10Cnt(w, carry);
00099     }
00100 
00101     static uint32_t word_rank(const uint64_t* data, size_type idx) {
00102         data = data+(idx>>6);
00103         uint64_t carry = (idx>63) ? *(data-1)>>63 : 0;
00104         return  bit_magic::b1Cnt(bit_magic::b10Map(*data, carry) & bit_magic::Li1Mask[idx&0x3F]);
00105     }
00106 
00107     static uint32_t full_word_rank(const uint64_t* data, size_type idx) {
00108         data = data+(idx>>6);
00109         uint64_t carry = (idx>63) ? *(data-1)>>63 : 0;
00110         return  bit_magic::b1Cnt(bit_magic::b10Map(*data, carry));
00111     }
00112 
00113     static uint64_t init_carry() {
00114         return 0;
00115     }
00116 };
00117 
00118 template<>
00119 struct rank_support_v_trait<01,2> {
00120     typedef rank_support::size_type     size_type;
00121 
00122     static size_type args_in_the_word(uint64_t w, uint64_t& carry) {
00123         return bit_magic::b01Cnt(w, carry);
00124     }
00125 
00126     static uint32_t word_rank(const uint64_t* data, size_type idx) {
00127         data = data+(idx>>6);
00128         uint64_t carry = (idx>63) ? *(data-1)>>63 : 0;
00129         return  bit_magic::b1Cnt(bit_magic::b01Map(*data, carry) & bit_magic::Li1Mask[idx&0x3F]);
00130     }
00131 
00132     static uint32_t full_word_rank(const uint64_t* data, size_type idx) {
00133         data = data+(idx>>6);
00134         uint64_t carry = (idx>63) ? *(data-1)>>63 : 0;
00135         return  bit_magic::b1Cnt(bit_magic::b01Map(*data, carry));
00136     }
00137 
00138     static uint64_t init_carry() {
00139         return 1;
00140     }
00141 };
00142 
00144 
00157 template<uint8_t b=1, uint8_t pattern_len=1>
00158 class rank_support_v : public rank_support
00159 {
00160     public:
00161         typedef bit_vector bit_vector_type;
00162     private:
00163         int_vector<64> m_basic_block; // basic block for interleaved storage of superblockrank and blockrank
00164     public:
00165         explicit rank_support_v(const bit_vector* v = NULL);
00166         rank_support_v(const rank_support_v& rs);
00167         ~rank_support_v();
00168         void init(const bit_vector* v=NULL);
00169         const size_type rank(size_type idx) const;
00170         const size_type operator()(size_type idx)const;
00171         const size_type size()const;
00172         size_type serialize(std::ostream& out, structure_tree_node* v=NULL, std::string name="")const;
00173         void load(std::istream& in, const int_vector<1>* v=NULL);
00174         void set_vector(const bit_vector* v=NULL);
00175 
00177 
00179         rank_support_v& operator=(const rank_support_v& rs);
00181 
00185         void swap(rank_support_v& rs);
00187 
00192         bool operator==(const rank_support_v& rs)const;
00194 
00199         bool operator!=(const rank_support_v& rs)const;
00200 };
00201 
00202 template<uint8_t b, uint8_t pattern_len>
00203 inline rank_support_v<b, pattern_len>::rank_support_v(const bit_vector* v)
00204 {
00205     init(v);
00206 }
00207 
00208 template<uint8_t b, uint8_t pattern_len>
00209 inline rank_support_v<b, pattern_len>::rank_support_v(const rank_support_v& rs)
00210 {
00211     m_v = rs.m_v;
00212     m_basic_block = rs.m_basic_block;
00213 }
00214 
00215 
00216 template<uint8_t b, uint8_t pattern_len>
00217 inline void rank_support_v<b, pattern_len>::set_vector(const bit_vector* v)
00218 {
00219     m_v = v;
00220 }
00221 
00222 template<uint8_t b, uint8_t pattern_len>
00223 inline const typename rank_support_v<b, pattern_len>::size_type rank_support_v<b, pattern_len>::size()const
00224 {
00225     return m_v->size();
00226 }
00227 
00228 template<uint8_t b, uint8_t pattern_len>
00229 inline void rank_support_v<b, pattern_len>::init(const bit_vector* v)
00230 {
00231     set_vector(v);
00232     if (v == NULL) {
00233         return;
00234     } else if (v->empty()) {
00235         m_basic_block = int_vector<64>(2,0);   // resize structure for basic_blocks
00236         return;
00237     }
00238     size_type basic_block_size = ((v->capacity() >> 9)+1)<<1;
00239     m_basic_block.resize(basic_block_size);   // resize structure for basic_blocks
00240     if (m_basic_block.empty())
00241         return;
00242     const uint64_t* data = m_v->data();
00243     size_type i, j=0;
00244     m_basic_block[0] = m_basic_block[1] = 0;
00245 
00246     uint64_t carry = rank_support_v_trait<b, pattern_len>::init_carry();
00247     uint64_t sum = rank_support_v_trait<b, pattern_len>::args_in_the_word(*data, carry), second_level_cnt = 0;
00248     for (i = 1; i < (m_v->capacity()>>6) ; ++i) {
00249         if (!(i&0x7)) {// if i%8==0
00250             j += 2;
00251             m_basic_block[j-1] = second_level_cnt;
00252             m_basic_block[j]    = m_basic_block[j-2] + sum;
00253             second_level_cnt = sum = 0;
00254         } else {
00255             second_level_cnt |= sum<<(63-9*(i&0x7));//  54, 45, 36, 27, 18, 9, 0
00256         }
00257         sum += rank_support_v_trait<b, pattern_len>::args_in_the_word(*(++data), carry);
00258     }
00259     if (i&0x7) { // if i%8 != 0
00260         second_level_cnt |= sum << (63-9*(i&0x7));
00261         m_basic_block[j+1] = second_level_cnt;
00262     } else { // if i%8 == 0
00263         j += 2;
00264         m_basic_block[j-1] = second_level_cnt;
00265         m_basic_block[j]   = m_basic_block[j-2] + sum;
00266         m_basic_block[j+1] = 0;
00267     }
00268 }
00269 
00270 template<uint8_t b, uint8_t pattern_len>
00271 inline const typename rank_support_v<b, pattern_len>::size_type rank_support_v<b, pattern_len>::rank(size_type idx)const
00272 {
00273     const uint64_t* p = m_basic_block.data() + ((idx>>8)&0xFFFFFFFFFFFFFFFEULL);// (idx/512)*2
00274     if (idx&0x3F)  // if (idx%64)!=0
00275         return  *p + ((*(p+1)>>(63 - 9*((idx&0x1FF)>>6)))&0x1FF) +
00276                 rank_support_v_trait<b, pattern_len>::word_rank(m_v->data(), idx);
00277     else
00278         return  *p + ((*(p+1)>>(63 - 9*((idx&0x1FF)>>6)))&0x1FF);
00279 }
00280 
00281 
00282 template<uint8_t b, uint8_t pattern_len>
00283 inline const typename rank_support_v<b, pattern_len>::size_type rank_support_v<b, pattern_len>::operator()(size_type idx)const
00284 {
00285     return rank(idx);
00286 }
00287 
00288 template<uint8_t b, uint8_t pattern_len>
00289 inline rank_support_v<b, pattern_len>::~rank_support_v() {}
00290 
00291 
00292 template<uint8_t b, uint8_t pattern_len>
00293 inline typename rank_support_v<b, pattern_len>::size_type rank_support_v<b, pattern_len>::serialize(std::ostream& out, structure_tree_node* v, std::string name)const
00294 {
00295     size_type written_bytes = 0;
00296     structure_tree_node* child = structure_tree::add_child(v, name, util::class_name(*this));
00297     written_bytes += m_basic_block.serialize(out, child, "cumulative_counts");
00298     structure_tree::add_size(child, written_bytes);
00299     return written_bytes;
00300 }
00301 
00302 template<uint8_t b, uint8_t pattern_len>
00303 inline void rank_support_v<b, pattern_len>::load(std::istream& in, const int_vector<1>* v)
00304 {
00305     set_vector(v);
00306     assert(m_v != NULL); // supported bit vector should be known
00307     m_basic_block.load(in);
00308 }
00309 
00310 template<uint8_t b, uint8_t pattern_len>
00311 inline rank_support_v<b, pattern_len>& rank_support_v<b, pattern_len>::operator=(const rank_support_v& rs)
00312 {
00313     if (this != &rs) {
00314         set_vector(rs.m_v);
00315         m_basic_block = rs.m_basic_block;
00316     }
00317     return *this;
00318 }
00319 
00320 template<uint8_t b, uint8_t pattern_len>
00321 inline void rank_support_v<b, pattern_len>::swap(rank_support_v& rs)
00322 {
00323     if (this != &rs) { // if rs and _this_ are not the same object
00324         m_basic_block.swap(rs.m_basic_block);
00325     }
00326 }
00327 
00328 // TODO: == operator remove pointer comparison
00329 template<uint8_t b, uint8_t pattern_len>
00330 inline bool rank_support_v<b, pattern_len>::operator==(const rank_support_v& rs)const
00331 {
00332     if (this == &rs)
00333         return true;
00334     return m_basic_block == rs.m_basic_block and *(rs.m_v) == *m_v;
00335 }
00336 
00337 template<uint8_t b, uint8_t pattern_len>
00338 inline bool rank_support_v<b, pattern_len>::operator!=(const rank_support_v& rs)const
00339 {
00340     return !(*this == rs);
00341 }
00342 
00343 }// end namespace sds
00344 
00345 #endif // end file