SDSL: Succinct Data Structure Library
A C++ template library for succinct data structures
|
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