00001 #ifndef BMVMIN__H__INCLUDED__
00002 #define BMVMIN__H__INCLUDED__
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 namespace bm
00030 {
00031
00032
00033 #define BM_MINISET_GAPLEN (bm::gap_len_table<true>::_len[0])
00034 #define BM_MINISET_ARRSIZE(x) ((x / 32) + ( (x % 32) && 1 ))
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 template <class A, size_t N> class miniset
00054 {
00055 public:
00056
00057 miniset()
00058 : m_buf(0),
00059 m_type(1)
00060 {}
00061
00062 miniset(const miniset& mset)
00063 {
00064 if (mset.m_buf)
00065 {
00066 if (mset.m_type)
00067 init_gapbuf(mset.m_buf);
00068 else
00069 init_bitbuf(mset.m_buf);
00070 }
00071 else
00072 {
00073 m_type = mset.m_type;
00074 m_buf = 0;
00075 }
00076 }
00077
00078 ~miniset()
00079 {
00080 if (m_buf)
00081 {
00082 A::deallocate(m_buf, m_type ?
00083 (BM_MINISET_GAPLEN / (sizeof(bm::word_t) / sizeof(bm::gap_word_t)))
00084 :
00085 (BM_MINISET_ARRSIZE(N)));
00086 }
00087 }
00088
00089
00090 unsigned test(bm::id_t n) const
00091 {
00092 return
00093 !m_buf ? 0
00094 :
00095 m_type ?
00096 gap_test((gap_word_t*)m_buf, n)
00097 :
00098 m_buf[n>>bm::set_word_shift] & (1<<(n & bm::set_word_mask));
00099 }
00100
00101 void set(bm::id_t n, bool val=true)
00102 {
00103 if (m_type == 0)
00104 {
00105 if (!m_buf)
00106 {
00107 if (!val) return;
00108 init_bitbuf(0);
00109 }
00110
00111 unsigned nword = n >> bm::set_word_shift;
00112 unsigned mask = unsigned(1) << (n & bm::set_word_mask);
00113
00114 val ? (m_buf[nword] |= mask) : (m_buf[nword] &= ~mask);
00115 }
00116 else
00117 {
00118 if (!m_buf)
00119 {
00120 if (!val) return;
00121 init_gapbuf(0);
00122 }
00123
00124 unsigned is_set;
00125 unsigned new_block_len =
00126 gap_set_value(val, (gap_word_t*)m_buf, n, &is_set);
00127
00128 if (new_block_len > unsigned(BM_MINISET_GAPLEN-4))
00129 {
00130 convert_buf();
00131 }
00132 }
00133 }
00134
00135 unsigned mem_used() const
00136 {
00137 return sizeof(*this) +
00138 m_buf ?
00139 (m_type ? (BM_MINISET_GAPLEN * sizeof(gap_word_t))
00140 : (BM_MINISET_ARRSIZE(N) * sizeof(bm::word_t)))
00141 : 0;
00142 }
00143
00144 void swap(miniset& mset)
00145 {
00146 bm::word_t* buftmp = m_buf;
00147 m_buf = mset.m_buf;
00148 mset.m_buf = buftmp;
00149 unsigned typetmp = m_type;
00150 m_type = mset.m_type;
00151 mset.m_type = typetmp;
00152 }
00153
00154
00155 private:
00156
00157 void init_bitbuf(bm::word_t* buf)
00158 {
00159 unsigned arr_size = BM_MINISET_ARRSIZE(N);
00160 m_buf = A::allocate(arr_size, 0);
00161 if (buf)
00162 {
00163 ::memcpy(m_buf, buf, arr_size * sizeof(bm::word_t));
00164 }
00165 else
00166 {
00167 ::memset(m_buf, 0, arr_size * sizeof(bm::word_t));
00168 }
00169 m_type = 0;
00170 }
00171
00172 void init_gapbuf(bm::word_t* buf)
00173 {
00174 unsigned arr_size =
00175 BM_MINISET_GAPLEN / (sizeof(bm::word_t) / sizeof(bm::gap_word_t));
00176 m_buf = A::allocate(arr_size, 0);
00177 if (buf)
00178 {
00179 ::memcpy(m_buf, buf, arr_size * sizeof(bm::word_t));
00180 }
00181 else
00182 {
00183 *m_buf = 0;
00184 gap_set_all((gap_word_t*)m_buf, bm::gap_max_bits, 0);
00185 }
00186 m_type = 1;
00187 }
00188
00189 void convert_buf()
00190 {
00191 unsigned arr_size = BM_MINISET_ARRSIZE(N);
00192 bm::word_t* buf = A::allocate(arr_size, 0);
00193
00194 gap_convert_to_bitset(buf, (gap_word_t*) m_buf, arr_size);
00195 arr_size =
00196 BM_MINISET_GAPLEN / (sizeof(bm::word_t) / sizeof(bm::gap_word_t));
00197 A::deallocate(m_buf, arr_size);
00198 m_buf = buf;
00199 m_type = 0;
00200 }
00201
00202 private:
00203 bm::word_t* m_buf;
00204 unsigned m_type;
00205 };
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 template<size_t N> class bvmini
00217 {
00218 public:
00219
00220 bvmini(int start_strategy = 0)
00221 {
00222 ::memset(m_buf, 0, sizeof(m_buf));
00223 }
00224
00225 bvmini(const bvmini& mset)
00226 {
00227 ::memcpy(m_buf, mset.m_buf, sizeof(m_buf));
00228 }
00229
00230
00231
00232 unsigned test(bm::id_t n) const
00233 {
00234 return m_buf[n>>bm::set_word_shift] & (1<<(n & bm::set_word_mask));
00235 }
00236
00237 void set(bm::id_t n, bool val=true)
00238 {
00239 unsigned nword = n >> bm::set_word_shift;
00240 unsigned mask = unsigned(1) << (n & bm::set_word_mask);
00241
00242 val ? (m_buf[nword] |= mask) : (m_buf[nword] &= ~mask);
00243 }
00244
00245 unsigned mem_used() const
00246 {
00247 return sizeof(*this);
00248 }
00249
00250 void swap(bvmini& mset)
00251 {
00252 for (unsigned i = 0; i < BM_MINISET_ARRSIZE(N); ++i)
00253 {
00254 bm::word_t tmp = m_buf[i];
00255 m_buf[i] = mset.m_buf[i];
00256 mset.m_buf[i] = tmp;
00257 }
00258 }
00259
00260 private:
00261 bm::word_t m_buf[BM_MINISET_ARRSIZE(N)];
00262 };
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 template<class A> class bvector_mini
00274 {
00275 public:
00276 bvector_mini(unsigned size)
00277 : m_buf(0),
00278 m_size(size)
00279 {
00280 unsigned arr_size = (size / 32) + 1;
00281 m_buf = A::allocate(arr_size, 0);
00282 ::memset(m_buf, 0, arr_size * sizeof(unsigned));
00283 }
00284 bvector_mini(const bvector_mini& bvect)
00285 : m_size(bvect.m_size)
00286 {
00287 unsigned arr_size = (m_size / 32) + 1;
00288 m_buf = A::allocate(arr_size, 0);
00289 ::memcpy(m_buf, bvect.m_buf, arr_size * sizeof(unsigned));
00290 }
00291
00292 ~bvector_mini()
00293 {
00294 A::deallocate(m_buf, (m_size / 32) + 1);
00295 }
00296
00297
00298 int is_bit_true(unsigned pos) const
00299 {
00300 unsigned char mask = (unsigned char)((char)0x1 << (pos & 7));
00301 unsigned char* offs = (unsigned char*)m_buf + (pos >> 3);
00302
00303 return (*offs) & mask;
00304 }
00305
00306
00307 void set_bit(unsigned pos)
00308 {
00309 unsigned char mask = (unsigned char)(0x1 << (pos & 7));
00310 unsigned char* offs = (unsigned char*)m_buf + (pos >> 3);
00311 *offs |= mask;
00312 }
00313
00314
00315
00316 void clear_bit(unsigned pos)
00317 {
00318 unsigned char mask = (unsigned char)(0x1 << (pos & 7));
00319 unsigned char* offs = (unsigned char*)m_buf + (pos >> 3);
00320
00321 *offs &= ~mask;
00322 }
00323
00324
00325 unsigned bit_count() const
00326 {
00327 register unsigned count = 0;
00328 const unsigned* end = m_buf + (m_size / 32)+1;
00329
00330 for (unsigned* start = m_buf; start < end; ++start)
00331 {
00332 register unsigned value = *start;
00333 for (count += (value!=0); value &= value - 1; ++count);
00334 }
00335 return count;
00336 }
00337
00338
00339 int compare(const bvector_mini& bvect)
00340 {
00341 unsigned cnt1 = bit_count();
00342 unsigned cnt2 = bvect.bit_count();
00343
00344 if (!cnt1 && !cnt2) return 0;
00345
00346 unsigned cnt_min = cnt1 < cnt2 ? cnt1 : cnt2;
00347
00348 if (!cnt_min) return cnt1 ? 1 : -1;
00349
00350 unsigned idx1 = get_first();
00351 unsigned idx2 = bvect.get_first();
00352
00353 for (unsigned i = 0; i < cnt_min; ++i)
00354 {
00355 if (idx1 != idx2)
00356 {
00357 return idx1 < idx2 ? 1 : -1;
00358 }
00359 idx1 = get_next(idx1);
00360 idx2 = bvect.get_next(idx2);
00361 }
00362
00363 BM_ASSERT(idx1==0 || idx2==0);
00364
00365 if (idx1 != idx2)
00366 {
00367 if (!idx1) return -1;
00368 if (!idx2) return 1;
00369 return idx1 < idx2 ? 1 : -1;
00370 }
00371
00372 return 0;
00373 }
00374
00375
00376
00377 unsigned get_first() const
00378 {
00379 unsigned pos = 0;
00380 const unsigned char* ptr = (unsigned char*) m_buf;
00381
00382 for (unsigned i = 0; i < (m_size/8)+1; ++i)
00383 {
00384 register unsigned char w = ptr[i];
00385
00386
00387 if (w != 0)
00388 {
00389 while ((w & 1) == 0)
00390 {
00391 w >>= 1;
00392 ++pos;
00393 }
00394 return pos;
00395 }
00396 pos += sizeof(unsigned char) * 8;
00397 }
00398 return 0;
00399 }
00400
00401
00402
00403 unsigned get_next(unsigned idx) const
00404 {
00405 register unsigned i;
00406
00407 for (i = idx+1; i < m_size; ++i)
00408 {
00409 unsigned char* offs = (unsigned char*)m_buf + (i >> 3);
00410 if (*offs)
00411 {
00412 unsigned char mask = (unsigned char)((char)0x1 << (i & 7));
00413
00414 if (*offs & mask)
00415 {
00416 return i;
00417 }
00418 }
00419 else
00420 {
00421 i += 7;
00422 }
00423 }
00424 return 0;
00425 }
00426
00427
00428 void combine_and(const bvector_mini& bvect)
00429 {
00430 const unsigned* end = m_buf + (m_size / 32)+1;
00431
00432 const unsigned* src = bvect.get_buf();
00433
00434 for (unsigned* start = m_buf; start < end; ++start)
00435 {
00436 *start &= *src++;
00437 }
00438 }
00439
00440 void combine_xor(const bvector_mini& bvect)
00441 {
00442 const unsigned* end = m_buf + (m_size / 32)+1;
00443
00444 const unsigned* src = bvect.get_buf();
00445
00446 for (unsigned* start = m_buf; start < end; ++start)
00447 {
00448 *start ^= *src++;
00449 }
00450 }
00451
00452
00453 void combine_or(const bvector_mini& bvect)
00454 {
00455 const unsigned* end = m_buf + (m_size / 32)+1;
00456
00457 const unsigned* src = bvect.get_buf();
00458
00459 for (unsigned* start = m_buf; start < end; ++start)
00460 {
00461 *start |= *src++;
00462 }
00463 }
00464
00465 void combine_sub(const bvector_mini& bvect)
00466 {
00467 const unsigned* end = m_buf + (m_size / 32)+1;
00468
00469 const unsigned* src = bvect.get_buf();
00470
00471 for (unsigned* start = m_buf; start < end; ++start)
00472 {
00473 *start &= ~(*src++);
00474 }
00475 }
00476
00477 const unsigned* get_buf() const { return m_buf; }
00478 unsigned mem_used() const
00479 {
00480 return sizeof(bvector_mini) + (m_size / 32) + 1;
00481 }
00482
00483 void swap(bvector_mini& bvm)
00484 {
00485 BM_ASSERT(m_size == bvm.m_size);
00486 bm::word_t* buftmp = m_buf;
00487 m_buf = bvm.m_buf;
00488 bvm.m_buf = buftmp;
00489 }
00490
00491 private:
00492 bm::word_t* m_buf;
00493 unsigned m_size;
00494 };
00495
00496
00497
00498 }
00499
00500 #endif