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_jmc.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_JMC
00022 #define INCLUDED_SDSL_RANK_SUPPORT_JMC
00023 
00024 #include "rank_support.hpp"
00025 #include "int_vector.hpp"
00026 
00028 namespace sdsl
00029 {
00030 
00032 
00036 class rank_support_jmc : public rank_support
00037 {
00038     public:
00039         typedef bit_vector bit_vector_type;
00040     private:
00041         size_type m_logn;
00042         int_vector<0> m_superblockrank;
00043         int_vector<0> m_blockrank;
00044     public:
00045         explicit rank_support_jmc(const int_vector<1>* v=NULL);
00046         rank_support_jmc(const rank_support_jmc& rs);
00047         ~rank_support_jmc();
00048         void init(const int_vector<1>* v=NULL);
00049         inline const size_type rank(size_type idx) const;
00050         inline const size_type operator()(size_type idx)const;
00051         size_type serialize(std::ostream& out, structure_tree_node* v=NULL, std::string name="")const;
00052         void load(std::istream& in, const int_vector<1>* v=NULL);
00053         void set_vector(const int_vector<1>* v);
00055 
00057         rank_support_jmc& operator=(const rank_support_jmc& rs);
00059 
00062         void swap(rank_support_jmc& rs);
00064 
00069         bool operator==(const rank_support_jmc& rs)const;
00071 
00076         bool operator!=(const rank_support_jmc& rs)const;
00077 };
00078 
00079 inline rank_support_jmc::rank_support_jmc(const int_vector<1>* v)
00080 {
00081     m_logn = 0;
00082     init(v);
00083 }
00084 
00085 inline rank_support_jmc::rank_support_jmc(const rank_support_jmc& rs) : rank_support()
00086 {
00087     set_vector(rs.m_v);
00088     m_superblockrank = rs.m_superblockrank;
00089     m_blockrank          = rs.m_blockrank;
00090 }
00091 
00092 inline rank_support_jmc& rank_support_jmc::operator=(const rank_support_jmc& rs)
00093 {
00094     if (this != &rs) {
00095         set_vector(rs.m_v);
00096         m_superblockrank = rs.m_superblockrank;
00097         m_blockrank             = rs.m_blockrank;
00098     }
00099     return *this;
00100 }
00101 
00102 inline void rank_support_jmc::swap(rank_support_jmc& rs)
00103 {
00104     if (this != &rs) { // if rs and _this_ are not the same object
00105         std::swap(m_logn, rs.m_logn);
00106         m_superblockrank.swap(rs.m_superblockrank);
00107         m_blockrank.swap(rs.m_blockrank);
00108     }
00109 }
00110 
00111 inline void rank_support_jmc::init(const int_vector<1>* v)
00112 {
00113     set_vector(v);
00114     if (m_v == NULL) return;
00115     if (m_v->empty()) {
00116         m_blockrank.set_int_width(1); m_superblockrank.set_int_width(1);
00117         m_blockrank.resize(1);          m_superblockrank.resize(1);
00118         m_blockrank[0] = 0; m_superblockrank[0] = 0;
00119         return;
00120     }
00121     m_blockrank.set_int_width(12);
00122     m_blockrank.resize((m_v->capacity()>>6) + (0==(m_v->size()&0x3F)));     // n/64 + 2*loglog 64
00123     m_superblockrank.set_int_width(m_logn);
00124     m_superblockrank.resize((m_blockrank.size()+63)>>6);
00125 
00126     m_blockrank[0]=0;
00127     m_superblockrank[0]=0;
00128     size_type cnt = 0, blockcnt = 0, wcnt = 0;
00129     const uint64_t* data = m_v->data();
00130     size_type i;
00131     for (i = 1; i < (m_v->capacity()>>6) ; ++i) {
00132         wcnt = bit_magic::b1Cnt(*data);
00133         ++data;
00134         blockcnt += wcnt;
00135         cnt      += wcnt;
00136         if ((i & 0x3F) == 0) {
00137             m_superblockrank[i>>6] = cnt;
00138             blockcnt = 0;
00139         }
00140         m_blockrank[i] = blockcnt;
00141     }
00142     if (0 == (m_v->size()&0x3F)) {
00143         wcnt = bit_magic::b1Cnt(*data);
00144         blockcnt += wcnt;
00145         cnt              += wcnt;
00146         if ((i & 0x3F) == 0) {
00147             m_superblockrank[i>>6] = cnt;
00148             blockcnt = 0;
00149         }
00150         m_blockrank[i] = blockcnt;
00151     }
00152 }
00153 
00154 inline const rank_support_jmc::size_type rank_support_jmc::rank(size_type idx)const
00155 {
00156     if ((idx & 0x3F) ==0)
00157         return m_blockrank[idx>>6]
00158                + m_superblockrank[idx>>12];
00159     return
00160         bit_magic::b1Cnt((*(m_v->data()+(idx>>6))&bit_magic::Li1Mask[idx & 0x3F]))
00161         + m_blockrank[idx>>6]
00162         + m_superblockrank[idx>>12];
00163 }
00164 
00165 inline const rank_support_jmc::size_type rank_support_jmc::operator()(size_type idx)const
00166 {
00167     return rank(idx);
00168 }
00169 
00170 inline rank_support_jmc::size_type rank_support_jmc::serialize(std::ostream& out, structure_tree_node* v, std::string name)const
00171 {
00172     size_type written_bytes = 0;
00173     structure_tree_node* child = structure_tree::add_child(v, name, util::class_name(*this));
00174     written_bytes += m_blockrank.serialize(out, child, "blockrank");
00175     written_bytes += m_superblockrank.serialize(out, child, "superblockrank");
00176     structure_tree::add_size(child, written_bytes);
00177     return written_bytes;
00178 }
00179 
00180 inline void rank_support_jmc::load(std::istream& in, const int_vector<1>* v)
00181 {
00182     set_vector(v);
00183     assert(m_v != NULL); // supported bit vector should be known
00184     m_blockrank.load(in);
00185     m_superblockrank.load(in);
00186 }
00187 
00188 inline rank_support_jmc::~rank_support_jmc()
00189 {
00190 }
00191 
00192 inline void rank_support_jmc::set_vector(const int_vector<1>* v)
00193 {
00194     if (v != NULL) {
00195         m_v = v;
00196         m_logn = bit_magic::l1BP(m_v->capacity())+1;
00197     }
00198 }
00199 
00200 inline bool rank_support_jmc::operator==(const rank_support_jmc& rs)const
00201 {
00202     if (this == &rs)
00203         return true;
00204     return m_logn == rs.m_logn
00205            and m_superblockrank == rs.m_superblockrank
00206            and m_blockrank == rs.m_blockrank
00207            and *(m_v) == *(rs.m_v);
00208 }
00209 
00210 inline bool rank_support_jmc::operator!=(const rank_support_jmc& rs)const
00211 {
00212     return !(*this == rs);
00213 }
00214 
00215 }// end namespace sds
00216 
00217 #endif // end file