00001 #ifndef BM__H__INCLUDED__
00002 #define BM__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
00030
00031
00032 #ifndef BM_NO_STL
00033 # include <iterator>
00034 #endif
00035
00036 #ifdef _MSC_VER
00037 #pragma warning( disable : 4311 4312)
00038 #endif
00039
00040
00041
00042 #include "bmconst.h"
00043 #include "bmdef.h"
00044
00045
00046
00047
00048
00049 #ifdef BMSSE42OPT
00050 # undef BMSSE2OPT
00051 # undef BM64OPT
00052 # define BMVECTOPT
00053 # include "bmsse4.h"
00054 #endif
00055
00056 #ifdef BMSSE2OPT
00057 # undef BM64OPT
00058 # define BMVECTOPT
00059 # include "bmsse2.h"
00060 #endif
00061
00062 #include "bmfwd.h"
00063 #include "bmfunc.h"
00064 #include "bmvmin.h"
00065 #include "encoding.h"
00066 #include "bmalloc.h"
00067 #include "bmblocks.h"
00068
00069 namespace bm
00070 {
00071
00072
00073 #ifdef BMCOUNTOPT
00074
00075 # define BMCOUNT_INC ++count_;
00076 # define BMCOUNT_DEC --count_;
00077 # define BMCOUNT_VALID(x) count_is_valid_ = x;
00078 # define BMCOUNT_SET(x) count_ = x; count_is_valid_ = true;
00079 # define BMCOUNT_ADJ(x) if (x) ++count_; else --count_;
00080
00081 #else
00082
00083 # define BMCOUNT_INC
00084 # define BMCOUNT_DEC
00085 # define BMCOUNT_VALID(x)
00086 # define BMCOUNT_SET(x)
00087 # define BMCOUNT_ADJ(x)
00088
00089 #endif
00090
00091
00092
00093 typedef bm::miniset<bm::block_allocator, bm::set_total_blocks> mem_save_set;
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 template<class Alloc, class MS>
00116 class bvector
00117 {
00118 public:
00119
00120 typedef Alloc allocator_type;
00121 typedef blocks_manager<Alloc, MS> blocks_manager_type;
00122
00123 typedef bm::id_t size_type;
00124
00125
00126 struct statistics : public bv_statistics
00127 {};
00128
00129
00130
00131
00132
00133
00134
00135
00136 class reference
00137 {
00138 public:
00139 reference(bvector<Alloc, MS>& bv, bm::id_t position)
00140 : bv_(bv),
00141 position_(position)
00142 {}
00143
00144 reference(const reference& ref)
00145 : bv_(ref.bv_),
00146 position_(ref.position_)
00147 {
00148 bv_.set(position_, ref.bv_.get_bit(position_));
00149 }
00150
00151 operator bool() const
00152 {
00153 return bv_.get_bit(position_);
00154 }
00155
00156 const reference& operator=(const reference& ref) const
00157 {
00158 bv_.set(position_, (bool)ref);
00159 return *this;
00160 }
00161
00162 const reference& operator=(bool value) const
00163 {
00164 bv_.set(position_, value);
00165 return *this;
00166 }
00167
00168 bool operator==(const reference& ref) const
00169 {
00170 return bool(*this) == bool(ref);
00171 }
00172
00173
00174 const reference& operator&=(bool value) const
00175 {
00176 bv_.set_bit_and(position_, value);
00177 return *this;
00178 }
00179
00180
00181 const reference& operator|=(bool value) const
00182 {
00183 if (value != bv_.get_bit(position_))
00184 {
00185 bv_.set_bit(position_);
00186 }
00187 return *this;
00188 }
00189
00190
00191 const reference& operator^=(bool value) const
00192 {
00193 bv_.set(position_, value != bv_.get_bit(position_));
00194 return *this;
00195 }
00196
00197
00198 bool operator!() const
00199 {
00200 return !bv_.get_bit(position_);
00201 }
00202
00203
00204 bool operator~() const
00205 {
00206 return !bv_.get_bit(position_);
00207 }
00208
00209
00210 reference& flip()
00211 {
00212 bv_.flip(position_);
00213 return *this;
00214 }
00215
00216 private:
00217 bvector<Alloc, MS>& bv_;
00218 bm::id_t position_;
00219 };
00220
00221 typedef bool const_reference;
00222
00223
00224
00225
00226
00227 class iterator_base
00228 {
00229 friend class bvector;
00230 public:
00231 iterator_base() : bv_(0), position_(bm::id_max), block_(0) {}
00232
00233 bool operator==(const iterator_base& it) const
00234 {
00235 return (position_ == it.position_) && (bv_ == it.bv_);
00236 }
00237
00238 bool operator!=(const iterator_base& it) const
00239 {
00240 return ! operator==(it);
00241 }
00242
00243 bool operator < (const iterator_base& it) const
00244 {
00245 return position_ < it.position_;
00246 }
00247
00248 bool operator <= (const iterator_base& it) const
00249 {
00250 return position_ <= it.position_;
00251 }
00252
00253 bool operator > (const iterator_base& it) const
00254 {
00255 return position_ > it.position_;
00256 }
00257
00258 bool operator >= (const iterator_base& it) const
00259 {
00260 return position_ >= it.position_;
00261 }
00262
00263
00264
00265
00266
00267
00268 bool valid() const
00269 {
00270 return position_ != bm::id_max;
00271 }
00272
00273
00274
00275
00276
00277 void invalidate()
00278 {
00279 position_ = bm::id_max;
00280 }
00281
00282 public:
00283
00284
00285 struct bitblock_descr
00286 {
00287 const bm::word_t* ptr;
00288 unsigned bits[32];
00289 unsigned idx;
00290 unsigned cnt;
00291 bm::id_t pos;
00292 };
00293
00294
00295 struct dgap_descr
00296 {
00297 const gap_word_t* ptr;
00298 gap_word_t gap_len;
00299 };
00300
00301 protected:
00302 bm::bvector<Alloc, MS>* bv_;
00303 bm::id_t position_;
00304 const bm::word_t* block_;
00305 unsigned block_type_;
00306 unsigned block_idx_;
00307
00308
00309 union block_descr
00310 {
00311 bitblock_descr bit_;
00312 dgap_descr gap_;
00313 } bdescr_;
00314 };
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 class insert_iterator
00332 {
00333 public:
00334 #ifndef BM_NO_STL
00335 typedef std::output_iterator_tag iterator_category;
00336 #endif
00337 typedef unsigned value_type;
00338 typedef void difference_type;
00339 typedef void pointer;
00340 typedef void reference;
00341
00342 insert_iterator(bvector<Alloc, MS>& bvect)
00343 : bvect_(bvect),
00344 max_bit_(bvect.size())
00345 {
00346 }
00347
00348 insert_iterator& operator=(bm::id_t n)
00349 {
00350 BM_ASSERT(n < bm::id_max);
00351
00352 if (n >= max_bit_)
00353 {
00354 max_bit_ = n;
00355 if (n >= bvect_.size())
00356 {
00357 bvect_.resize(n + 1);
00358 }
00359 }
00360
00361 bvect_.set(n);
00362 return *this;
00363 }
00364
00365
00366 insert_iterator& operator*() { return *this; }
00367
00368 insert_iterator& operator++() { return *this; }
00369
00370 insert_iterator& operator++(int) { return *this; }
00371
00372 protected:
00373 bm::bvector<Alloc, MS>& bvect_;
00374 bm::id_t max_bit_;
00375 };
00376
00377
00378
00379
00380
00381 class enumerator : public iterator_base
00382 {
00383 public:
00384 #ifndef BM_NO_STL
00385 typedef std::input_iterator_tag iterator_category;
00386 #endif
00387 typedef unsigned value_type;
00388 typedef unsigned difference_type;
00389 typedef unsigned* pointer;
00390 typedef unsigned& reference;
00391
00392 public:
00393 enumerator() : iterator_base() {}
00394 enumerator(const bvector<Alloc, MS>* bvect, int position)
00395 : iterator_base()
00396 {
00397 this->bv_ = const_cast<bvector<Alloc, MS>*>(bvect);
00398 if (position == 0)
00399 {
00400 go_first();
00401 }
00402 else
00403 {
00404 this->invalidate();
00405 }
00406 }
00407
00408 bm::id_t operator*() const
00409 {
00410 return this->position_;
00411 }
00412
00413 enumerator& operator++()
00414 {
00415 return this->go_up();
00416 }
00417
00418 enumerator operator++(int)
00419 {
00420 enumerator tmp = *this;
00421 this->go_up();
00422 return tmp;
00423 }
00424
00425
00426 void go_first()
00427 {
00428 BM_ASSERT(this->bv_);
00429
00430 #ifdef BMCOUNTOPT
00431 if (this->bv_->count_is_valid_ &&
00432 this->bv_->count_ == 0)
00433 {
00434 this->invalidate();
00435 return;
00436 }
00437 #endif
00438
00439 blocks_manager_type* bman = &(this->bv_->blockman_);
00440 bm::word_t*** blk_root = bman->blocks_root();
00441
00442 this->block_idx_ = this->position_= 0;
00443 unsigned i, j;
00444
00445 for (i = 0; i < bman->top_block_size(); ++i)
00446 {
00447 bm::word_t** blk_blk = blk_root[i];
00448
00449 if (blk_blk == 0)
00450 {
00451 this->block_idx_ += bm::set_array_size;
00452 this->position_ += bm::bits_in_array;
00453 continue;
00454 }
00455
00456
00457 for (j = 0; j < bm::set_array_size; ++j,++(this->block_idx_))
00458 {
00459 this->block_ = blk_blk[j];
00460
00461 if (this->block_ == 0)
00462 {
00463 this->position_ += bits_in_block;
00464 continue;
00465 }
00466
00467 if (BM_IS_GAP((*bman), this->block_, this->block_idx_))
00468 {
00469 this->block_type_ = 1;
00470 if (search_in_gapblock())
00471 {
00472 return;
00473 }
00474 }
00475 else
00476 {
00477 this->block_type_ = 0;
00478 if (search_in_bitblock())
00479 {
00480 return;
00481 }
00482 }
00483
00484 }
00485
00486 }
00487
00488 this->invalidate();
00489 }
00490
00491 enumerator& go_up()
00492 {
00493
00494 ++this->position_;
00495 typedef typename iterator_base::block_descr block_descr_type;
00496
00497 block_descr_type* bdescr = &(this->bdescr_);
00498
00499 switch (this->block_type_)
00500 {
00501 case 0:
00502 {
00503
00504
00505
00506
00507 unsigned idx = ++(bdescr->bit_.idx);
00508 if (idx < bdescr->bit_.cnt)
00509 {
00510 this->position_ = bdescr->bit_.pos +
00511 bdescr->bit_.bits[idx];
00512 return *this;
00513 }
00514 this->position_ += 31 - bdescr->bit_.bits[--idx];
00515
00516 const bm::word_t* pend = this->block_ + bm::set_block_size;
00517
00518 while (++(bdescr->bit_.ptr) < pend)
00519 {
00520 bm::word_t w = *(bdescr->bit_.ptr);
00521 if (w)
00522 {
00523 bdescr->bit_.idx = 0;
00524 bdescr->bit_.pos = this->position_;
00525 bdescr->bit_.cnt = bm::bit_list_4(w, bdescr->bit_.bits);
00526 this->position_ += bdescr->bit_.bits[0];
00527 return *this;
00528 }
00529 else
00530 {
00531 this->position_ += 32;
00532 }
00533 }
00534
00535 }
00536 break;
00537
00538 case 1:
00539 {
00540 if (--(bdescr->gap_.gap_len))
00541 {
00542 return *this;
00543 }
00544
00545
00546 if (*(bdescr->gap_.ptr) == bm::gap_max_bits - 1)
00547 {
00548 break;
00549 }
00550 gap_word_t prev = *(bdescr->gap_.ptr);
00551 register unsigned val = *(++(bdescr->gap_.ptr));
00552
00553 this->position_ += val - prev;
00554
00555
00556 if (*(bdescr->gap_.ptr) == bm::gap_max_bits - 1)
00557 {
00558 break;
00559 }
00560 prev = *(bdescr->gap_.ptr);
00561 val = *(++(bdescr->gap_.ptr));
00562 bdescr->gap_.gap_len = val - prev;
00563 return *this;
00564 }
00565
00566 default:
00567 BM_ASSERT(0);
00568
00569 }
00570
00571
00572
00573
00574 ++(this->block_idx_);
00575 unsigned i = this->block_idx_ >> bm::set_array_shift;
00576 unsigned top_block_size = this->bv_->blockman_.top_block_size();
00577 for (; i < top_block_size; ++i)
00578 {
00579 bm::word_t** blk_blk = this->bv_->blockman_.blocks_root()[i];
00580 if (blk_blk == 0)
00581 {
00582 this->block_idx_ += bm::set_array_size;
00583 this->position_ += bm::bits_in_array;
00584 continue;
00585 }
00586
00587 unsigned j = this->block_idx_ & bm::set_array_mask;
00588
00589 for(; j < bm::set_array_size; ++j, ++(this->block_idx_))
00590 {
00591 this->block_ = blk_blk[j];
00592
00593 if (this->block_ == 0)
00594 {
00595 this->position_ += bm::bits_in_block;
00596 continue;
00597 }
00598
00599 if (BM_IS_GAP((this->bv_->blockman_),
00600 this->block_,
00601 this->block_idx_))
00602 {
00603 this->block_type_ = 1;
00604 if (search_in_gapblock())
00605 {
00606 return *this;
00607 }
00608 }
00609 else
00610 {
00611 this->block_type_ = 0;
00612 if (search_in_bitblock())
00613 {
00614 return *this;
00615 }
00616 }
00617
00618
00619 }
00620
00621 }
00622
00623
00624 this->invalidate();
00625 return *this;
00626 }
00627
00628
00629 private:
00630 bool search_in_bitblock()
00631 {
00632 BM_ASSERT(this->block_type_ == 0);
00633
00634 typedef typename iterator_base::block_descr block_descr_type;
00635 block_descr_type* bdescr = &(this->bdescr_);
00636
00637
00638 bdescr->bit_.ptr = this->block_;
00639
00640 const word_t* ptr_end = this->block_ + bm::set_block_size;
00641
00642 do
00643 {
00644 register bm::word_t w = *(bdescr->bit_.ptr);
00645
00646 if (w)
00647 {
00648 bdescr->bit_.idx = 0;
00649 bdescr->bit_.pos = this->position_;
00650 bdescr->bit_.cnt =
00651 bm::bit_list_4(w, bdescr->bit_.bits);
00652 this->position_ += bdescr->bit_.bits[0];
00653
00654 return true;
00655 }
00656 else
00657 {
00658 this->position_ += 32;
00659 }
00660
00661 }
00662 while (++(bdescr->bit_.ptr) < ptr_end);
00663
00664 return false;
00665 }
00666
00667 bool search_in_gapblock()
00668 {
00669 BM_ASSERT(this->block_type_ == 1);
00670
00671 typedef typename iterator_base::block_descr block_descr_type;
00672 block_descr_type* bdescr = &(this->bdescr_);
00673
00674 bdescr->gap_.ptr = BMGAP_PTR(this->block_);
00675 unsigned bitval = *(bdescr->gap_.ptr) & 1;
00676
00677 ++(bdescr->gap_.ptr);
00678
00679 do
00680 {
00681 register unsigned val = *(bdescr->gap_.ptr);
00682
00683 if (bitval)
00684 {
00685 gap_word_t* first = BMGAP_PTR(this->block_) + 1;
00686 if (bdescr->gap_.ptr == first)
00687 {
00688 bdescr->gap_.gap_len = val + 1;
00689 }
00690 else
00691 {
00692 bdescr->gap_.gap_len =
00693 val - *(bdescr->gap_.ptr-1);
00694 }
00695
00696 return true;
00697 }
00698 this->position_ += val + 1;
00699
00700 if (val == bm::gap_max_bits - 1)
00701 {
00702 break;
00703 }
00704
00705 bitval ^= 1;
00706 ++(bdescr->gap_.ptr);
00707
00708 } while (1);
00709
00710 return false;
00711 }
00712
00713 };
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 class counted_enumerator : public enumerator
00725 {
00726 public:
00727 #ifndef BM_NO_STL
00728 typedef std::input_iterator_tag iterator_category;
00729 #endif
00730 counted_enumerator() : bit_count_(0){}
00731
00732 counted_enumerator(const enumerator& en)
00733 : enumerator(en)
00734 {
00735 if (this->valid())
00736 bit_count_ = 1;
00737 }
00738
00739 counted_enumerator& operator=(const enumerator& en)
00740 {
00741 enumerator* me = this;
00742 *me = en;
00743 if (this->valid())
00744 this->bit_count_ = 1;
00745 return *this;
00746 }
00747
00748 counted_enumerator& operator++()
00749 {
00750 this->go_up();
00751 if (this->valid())
00752 ++(this->bit_count_);
00753 return *this;
00754 }
00755
00756 counted_enumerator operator++(int)
00757 {
00758 counted_enumerator tmp(*this);
00759 this->go_up();
00760 if (this->valid())
00761 ++bit_count_;
00762 return tmp;
00763 }
00764
00765
00766
00767
00768
00769
00770 bm::id_t count() const { return bit_count_; }
00771
00772 private:
00773 bm::id_t bit_count_;
00774 };
00775
00776 friend class iterator_base;
00777 friend class enumerator;
00778
00779 public:
00780
00781 #ifdef BMCOUNTOPT
00782 bvector(strategy strat = BM_BIT,
00783 const gap_word_t* glevel_len = bm::gap_len_table<true>::_len,
00784 size_type bv_size = bm::id_max,
00785 const Alloc& alloc = Alloc())
00786 : count_(0),
00787 count_is_valid_(true),
00788 blockman_(glevel_len, bv_size, alloc),
00789 new_blocks_strat_(strat),
00790 size_(bv_size)
00791 {}
00792
00793 bvector(size_type bv_size,
00794 bm::strategy strat = BM_BIT,
00795 const gap_word_t* glevel_len = bm::gap_len_table<true>::_len,
00796 const Alloc& alloc = Alloc())
00797 : count_(0),
00798 count_is_valid_(true),
00799 blockman_(glevel_len, bv_size, alloc),
00800 new_blocks_strat_(strat),
00801 size_(bv_size)
00802 {}
00803
00804
00805 bvector(const bm::bvector<Alloc, MS>& bvect)
00806 : count_(bvect.count_),
00807 count_is_valid_(bvect.count_is_valid_),
00808 blockman_(bvect.blockman_),
00809 new_blocks_strat_(bvect.new_blocks_strat_),
00810 size_(bvect.size_)
00811 {}
00812
00813 #else
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832 bvector(strategy strat = BM_BIT,
00833 const gap_word_t* glevel_len = bm::gap_len_table<true>::_len,
00834 size_type bv_size = bm::id_max,
00835 const Alloc& alloc = Alloc())
00836 : blockman_(glevel_len, bv_size, alloc),
00837 new_blocks_strat_(strat),
00838 size_(bv_size)
00839 {}
00840
00841
00842
00843
00844 bvector(size_type bv_size,
00845 strategy strat = BM_BIT,
00846 const gap_word_t* glevel_len = bm::gap_len_table<true>::_len,
00847 const Alloc& alloc = Alloc())
00848 : blockman_(glevel_len, bv_size, alloc),
00849 new_blocks_strat_(strat),
00850 size_(bv_size)
00851 {}
00852
00853
00854 bvector(const bvector<Alloc, MS>& bvect)
00855 : blockman_(bvect.blockman_),
00856 new_blocks_strat_(bvect.new_blocks_strat_),
00857 size_(bvect.size_)
00858 {}
00859
00860 #endif
00861
00862 bvector& operator=(const bvector<Alloc, MS>& bvect)
00863 {
00864 clear(true);
00865 resize(bvect.size());
00866 bit_or(bvect);
00867 return *this;
00868 }
00869
00870 reference operator[](bm::id_t n)
00871 {
00872 BM_ASSERT(n < size_);
00873 return reference(*this, n);
00874 }
00875
00876
00877 bool operator[](bm::id_t n) const
00878 {
00879 BM_ASSERT(n < size_);
00880 return get_bit(n);
00881 }
00882
00883 void operator &= (const bvector<Alloc, MS>& bvect)
00884 {
00885 bit_and(bvect);
00886 }
00887
00888 void operator ^= (const bvector<Alloc, MS>& bvect)
00889 {
00890 bit_xor(bvect);
00891 }
00892
00893 void operator |= (const bvector<Alloc, MS>& bvect)
00894 {
00895 bit_or(bvect);
00896 }
00897
00898 void operator -= (const bvector<Alloc, MS>& bvect)
00899 {
00900 bit_sub(bvect);
00901 }
00902
00903 bool operator < (const bvector<Alloc, MS>& bvect) const
00904 {
00905 return compare(bvect) < 0;
00906 }
00907
00908 bool operator <= (const bvector<Alloc, MS>& bvect) const
00909 {
00910 return compare(bvect) <= 0;
00911 }
00912
00913 bool operator > (const bvector<Alloc, MS>& bvect) const
00914 {
00915 return compare(bvect) > 0;
00916 }
00917
00918 bool operator >= (const bvector<Alloc, MS>& bvect) const
00919 {
00920 return compare(bvect) >= 0;
00921 }
00922
00923 bool operator == (const bvector<Alloc, MS>& bvect) const
00924 {
00925 return compare(bvect) == 0;
00926 }
00927
00928 bool operator != (const bvector<Alloc, MS>& bvect) const
00929 {
00930 return compare(bvect) != 0;
00931 }
00932
00933 bvector<Alloc, MS> operator~() const
00934 {
00935 return bvector<Alloc, MS>(*this).invert();
00936 }
00937
00938 Alloc get_allocator() const
00939 {
00940 return blockman_.get_allocator();
00941 }
00942
00943
00944
00945
00946
00947
00948
00949
00950 bool set_bit(bm::id_t n, bool val = true)
00951 {
00952 BM_ASSERT(n < size_);
00953 return set_bit_no_check(n, val);
00954 }
00955
00956
00957
00958
00959
00960
00961
00962 bool set_bit_and(bm::id_t n, bool val = true)
00963 {
00964 BM_ASSERT(n < size_);
00965 return and_bit_no_check(n, val);
00966 }
00967
00968
00969
00970
00971
00972
00973
00974
00975 bool set_bit_conditional(bm::id_t n, bool val, bool condition)
00976 {
00977 BM_ASSERT(n < size_);
00978 if (val == condition) return false;
00979 return set_bit_conditional_impl(n, val, condition);
00980 }
00981
00982
00983
00984
00985
00986
00987
00988
00989 bvector<Alloc, MS>& set(bm::id_t n, bool val = true)
00990 {
00991 set_bit(n, val);
00992 return *this;
00993 }
00994
00995
00996
00997
00998
00999
01000
01001 bvector<Alloc, MS>& set()
01002 {
01003 BMCOUNT_VALID(false)
01004 set_range(0, size_ - 1, true);
01005 return *this;
01006 }
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020 bvector<Alloc, MS>& set_range(bm::id_t left,
01021 bm::id_t right,
01022 bool value = true);
01023
01024
01025
01026 insert_iterator inserter()
01027 {
01028 return insert_iterator(*this);
01029 }
01030
01031
01032
01033
01034
01035
01036 void clear_bit(bm::id_t n)
01037 {
01038 set(n, false);
01039 }
01040
01041
01042
01043
01044
01045
01046
01047
01048 void clear(bool free_mem = false)
01049 {
01050 blockman_.set_all_zero(free_mem);
01051 BMCOUNT_SET(0);
01052 }
01053
01054
01055
01056
01057
01058 bvector<Alloc, MS>& reset()
01059 {
01060 clear();
01061 return *this;
01062 }
01063
01064
01065
01066
01067
01068
01069 bm::id_t count() const;
01070
01071
01072
01073
01074 size_type capacity() const
01075 {
01076 return blockman_.capacity();
01077 }
01078
01079
01080
01081
01082 size_type size() const
01083 {
01084 return size_;
01085 }
01086
01087
01088
01089
01090
01091 void resize(size_type new_size);
01092
01093
01094
01095
01096
01097
01098
01099 unsigned count_blocks(unsigned* arr) const
01100 {
01101 bm::word_t*** blk_root = blockman_.get_rootblock();
01102 typename blocks_manager_type::block_count_arr_func func(blockman_, &(arr[0]));
01103 for_each_nzblock(blk_root, blockman_.effective_top_block_size(),
01104 bm::set_array_size, func);
01105 return func.last_block();
01106 }
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117 bm::id_t count_range(bm::id_t left,
01118 bm::id_t right,
01119 unsigned* block_count_arr=0) const;
01120
01121
01122 bm::id_t recalc_count()
01123 {
01124 BMCOUNT_VALID(false)
01125 return count();
01126 }
01127
01128
01129
01130
01131
01132
01133
01134
01135 void forget_count()
01136 {
01137 BMCOUNT_VALID(false)
01138 }
01139
01140
01141
01142
01143 bvector<Alloc, MS>& invert();
01144
01145
01146
01147
01148
01149
01150
01151 bool get_bit(bm::id_t n) const;
01152
01153
01154
01155
01156
01157
01158 bool test(bm::id_t n) const
01159 {
01160 return get_bit(n);
01161 }
01162
01163
01164
01165
01166
01167 bool any() const
01168 {
01169 #ifdef BMCOUNTOPT
01170 if (count_is_valid_ && count_) return true;
01171 #endif
01172
01173 word_t*** blk_root = blockman_.get_rootblock();
01174 if (!blk_root)
01175 return false;
01176 typename blocks_manager_type::block_any_func func(blockman_);
01177 return for_each_nzblock_if(blk_root,
01178 blockman_.effective_top_block_size(),
01179 bm::set_array_size,
01180 func);
01181 }
01182
01183
01184
01185
01186 bool none() const
01187 {
01188 return !any();
01189 }
01190
01191
01192
01193
01194
01195 bvector<Alloc, MS>& flip(bm::id_t n)
01196 {
01197 set(n, !get_bit(n));
01198 return *this;
01199 }
01200
01201
01202
01203
01204
01205 bvector<Alloc, MS>& flip()
01206 {
01207 return invert();
01208 }
01209
01210
01211
01212 void swap(bvector<Alloc, MS>& bv)
01213 {
01214 if (this != &bv)
01215 {
01216 blockman_.swap(bv.blockman_);
01217 bm::xor_swap(size_,bv.size_);
01218 #ifdef BMCOUNTOPT
01219 BMCOUNT_VALID(false)
01220 bv.recalc_count();
01221 #endif
01222 }
01223 }
01224
01225
01226
01227
01228
01229
01230
01231
01232 bm::id_t get_first() const { return check_or_next(0); }
01233
01234
01235
01236
01237
01238
01239
01240
01241 bm::id_t get_next(bm::id_t prev) const
01242 {
01243 return (++prev == bm::id_max) ? 0 : check_or_next(prev);
01244 }
01245
01246
01247
01248
01249
01250
01251
01252
01253 bm::id_t extract_next(bm::id_t prev)
01254 {
01255 return (++prev == bm::id_max) ? 0 : check_or_next_extract(prev);
01256 }
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270 void calc_stat(struct bm::bvector<Alloc, MS>::statistics* st) const;
01271
01272
01273
01274
01275
01276 bm::bvector<Alloc, MS>& bit_or(const bm::bvector<Alloc, MS>& vect)
01277 {
01278 BMCOUNT_VALID(false);
01279 combine_operation(vect, BM_OR);
01280 return *this;
01281 }
01282
01283
01284
01285
01286
01287 bm::bvector<Alloc, MS>& bit_and(const bm::bvector<Alloc, MS>& vect)
01288 {
01289 BMCOUNT_VALID(false);
01290 combine_operation(vect, BM_AND);
01291 return *this;
01292 }
01293
01294
01295
01296
01297
01298 bm::bvector<Alloc, MS>& bit_xor(const bm::bvector<Alloc, MS>& vect)
01299 {
01300 BMCOUNT_VALID(false);
01301 combine_operation(vect, BM_XOR);
01302 return *this;
01303 }
01304
01305
01306
01307
01308
01309 bm::bvector<Alloc, MS>& bit_sub(const bm::bvector<Alloc, MS>& vect)
01310 {
01311 BMCOUNT_VALID(false);
01312 combine_operation(vect, BM_SUB);
01313 return *this;
01314 }
01315
01316
01317
01318
01319
01320
01321
01322 void set_new_blocks_strat(strategy strat)
01323 {
01324 new_blocks_strat_ = strat;
01325 }
01326
01327
01328
01329
01330
01331
01332
01333 strategy get_new_blocks_strat() const
01334 {
01335 return new_blocks_strat_;
01336 }
01337
01338
01339
01340
01341
01342
01343
01344 enum optmode
01345 {
01346 opt_free_0 = 1,
01347 opt_free_01 = 2,
01348 opt_compress = 3
01349 };
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363 void optimize(bm::word_t* temp_block = 0,
01364 optmode opt_mode = opt_compress,
01365 statistics* stat = 0);
01366
01367
01368
01369
01370
01371
01372
01373
01374 void optimize_gap_size();
01375
01376
01377
01378
01379
01380
01381
01382
01383 void set_gap_levels(const gap_word_t* glevel_len);
01384
01385
01386
01387
01388
01389
01390
01391
01392 int compare(const bvector<Alloc, MS>& bvect) const;
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405 bm::word_t* allocate_tempblock() const
01406 {
01407 blocks_manager_type* bm =
01408 const_cast<blocks_manager_type*>(&blockman_);
01409 return bm->get_allocator().alloc_bit_block();
01410 }
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420 void free_tempblock(bm::word_t* block) const
01421 {
01422 blocks_manager_type* bm =
01423 const_cast<blocks_manager_type*>(&blockman_);
01424 bm->get_allocator().free_bit_block(block);
01425 }
01426
01427
01428
01429
01430 enumerator first() const
01431 {
01432 typedef typename bvector<Alloc, MS>::enumerator enumerator_type;
01433 return enumerator_type(this, 0);
01434 }
01435
01436
01437
01438
01439
01440 enumerator end() const
01441 {
01442 typedef typename bvector<Alloc, MS>::enumerator enumerator_type;
01443 return enumerator_type(this, 1);
01444 }
01445
01446
01447 const bm::word_t* get_block(unsigned nb) const
01448 {
01449 return blockman_.get_block(nb);
01450 }
01451
01452 void combine_operation(const bm::bvector<Alloc, MS>& bvect,
01453 bm::operation opcode);
01454
01455 private:
01456
01457 bm::id_t check_or_next(bm::id_t prev) const;
01458
01459
01460
01461
01462 bm::id_t check_or_next_extract(bm::id_t prev);
01463
01464
01465
01466
01467 bool set_bit_no_check(bm::id_t n, bool val);
01468
01469
01470
01471
01472 bool and_bit_no_check(bm::id_t n, bool val);
01473
01474 bool set_bit_conditional_impl(bm::id_t n, bool val, bool condition);
01475
01476
01477 void combine_operation_with_block(unsigned nb,
01478 unsigned gap,
01479 bm::word_t* blk,
01480 const bm::word_t* arg_blk,
01481 int arg_gap,
01482 bm::operation opcode);
01483 public:
01484 void combine_operation_with_block(unsigned nb,
01485 const bm::word_t* arg_blk,
01486 int arg_gap,
01487 bm::operation opcode)
01488 {
01489 bm::word_t* blk = const_cast<bm::word_t*>(get_block(nb));
01490 bool gap = BM_IS_GAP((*this), blk, nb);
01491 combine_operation_with_block(nb, gap, blk, arg_blk, arg_gap, opcode);
01492 }
01493 private:
01494 void combine_count_operation_with_block(unsigned nb,
01495 const bm::word_t* arg_blk,
01496 int arg_gap,
01497 bm::operation opcode)
01498 {
01499 const bm::word_t* blk = get_block(nb);
01500 bool gap = BM_IS_GAP((*this), blk, nb);
01501 combine_count_operation_with_block(nb, gap, blk, arg_blk, arg_gap, opcode);
01502 }
01503
01504
01505
01506
01507
01508
01509
01510 void extend_gap_block(unsigned nb, gap_word_t* blk)
01511 {
01512 blockman_.extend_gap_block(nb, blk);
01513 }
01514
01515
01516
01517
01518 void set_range_no_check(bm::id_t left,
01519 bm::id_t right,
01520 bool value);
01521 public:
01522
01523 const blocks_manager_type& get_blocks_manager() const
01524 {
01525 return blockman_;
01526 }
01527
01528 blocks_manager_type& get_blocks_manager()
01529 {
01530 return blockman_;
01531 }
01532
01533
01534 private:
01535
01536
01537
01538 #ifdef BMCOUNTOPT
01539 mutable id_t count_;
01540 mutable bool count_is_valid_;
01541 #endif
01542
01543 blocks_manager_type blockman_;
01544 strategy new_blocks_strat_;
01545 size_type size_;
01546 };
01547
01548
01549
01550
01551
01552
01553
01554 template<class Alloc, class MS>
01555 inline bvector<Alloc, MS> operator& (const bvector<Alloc, MS>& v1,
01556 const bvector<Alloc, MS>& v2)
01557 {
01558 #ifdef BM_USE_EXPLICIT_TEMP
01559 bvector<Alloc, MS> ret(v1);
01560 ret.bit_and(v2);
01561 return ret;
01562 #else
01563 return bvector<Alloc, MS>(v1).bit_and(v2);
01564 #endif
01565 }
01566
01567
01568
01569 template<class Alloc, class MS>
01570 inline bvector<Alloc, MS> operator| (const bvector<Alloc, MS>& v1,
01571 const bvector<Alloc>& v2)
01572 {
01573 #ifdef BM_USE_EXPLICIT_TEMP
01574 bvector<Alloc, MS> ret(v1);
01575 ret.bit_or(v2);
01576 return ret;
01577 #else
01578 return bvector<Alloc, MS>(v1).bit_or(v2);
01579 #endif
01580 }
01581
01582
01583
01584 template<class Alloc, class MS>
01585 inline bvector<Alloc, MS> operator^ (const bvector<Alloc, MS>& v1,
01586 const bvector<Alloc, MS>& v2)
01587 {
01588 #ifdef BM_USE_EXPLICIT_TEMP
01589 bvector<Alloc, MS> ret(v1);
01590 ret.bit_xor(v2);
01591 return ret;
01592 #else
01593 return bvector<Alloc, MS>(v1).bit_xor(v2);
01594 #endif
01595 }
01596
01597
01598
01599 template<class Alloc, class MS>
01600 inline bvector<Alloc, MS> operator- (const bvector<Alloc, MS>& v1,
01601 const bvector<Alloc, MS>& v2)
01602 {
01603 #ifdef BM_USE_EXPLICIT_TEMP
01604 bvector<Alloc, MS> ret(v1);
01605 ret.bit_sub(v2);
01606 return ret;
01607 #else
01608 return bvector<Alloc, MS>(v1).bit_sub(v2);
01609 #endif
01610 }
01611
01612
01613
01614
01615
01616
01617 template<typename Alloc, typename MS>
01618 bvector<Alloc, MS>& bvector<Alloc, MS>::set_range(bm::id_t left,
01619 bm::id_t right,
01620 bool value)
01621 {
01622 if (right < left)
01623 {
01624 return set_range(right, left, value);
01625 }
01626
01627 BM_ASSERT(left < size_);
01628 BM_ASSERT(right < size_);
01629
01630 BMCOUNT_VALID(false)
01631 BM_SET_MMX_GUARD
01632
01633 set_range_no_check(left, right, value);
01634
01635 return *this;
01636 }
01637
01638
01639
01640 template<typename Alloc, typename MS>
01641 bm::id_t bvector<Alloc, MS>::count() const
01642 {
01643 #ifdef BMCOUNTOPT
01644 if (count_is_valid_) return count_;
01645 #endif
01646 word_t*** blk_root = blockman_.get_rootblock();
01647 if (!blk_root)
01648 {
01649 BMCOUNT_SET(0);
01650 return 0;
01651 }
01652 typename blocks_manager_type::block_count_func func(blockman_);
01653 for_each_nzblock(blk_root, blockman_.effective_top_block_size(),
01654 bm::set_array_size, func);
01655
01656 BMCOUNT_SET(func.count());
01657 return func.count();
01658 }
01659
01660
01661
01662 template<typename Alloc, typename MS>
01663 void bvector<Alloc, MS>::resize(size_type new_size)
01664 {
01665 if (size_ == new_size) return;
01666 if (size_ < new_size)
01667 {
01668 blockman_.reserve(new_size);
01669 size_ = new_size;
01670 }
01671 else
01672 {
01673 set_range(new_size, size_ - 1, false);
01674 size_ = new_size;
01675 }
01676 }
01677
01678
01679
01680 template<typename Alloc, typename MS>
01681 bm::id_t bvector<Alloc, MS>::count_range(bm::id_t left,
01682 bm::id_t right,
01683 unsigned* block_count_arr) const
01684 {
01685 BM_ASSERT(left <= right);
01686
01687 unsigned count = 0;
01688
01689
01690 unsigned nblock_left = unsigned(left >> bm::set_block_shift);
01691 unsigned nblock_right = unsigned(right >> bm::set_block_shift);
01692
01693 const bm::word_t* block = blockman_.get_block(nblock_left);
01694 bool left_gap = BM_IS_GAP(blockman_, block, nblock_left);
01695
01696 unsigned nbit_left = unsigned(left & bm::set_block_mask);
01697 unsigned nbit_right = unsigned(right & bm::set_block_mask);
01698
01699 unsigned r =
01700 (nblock_left == nblock_right) ? nbit_right : (bm::bits_in_block-1);
01701
01702 typename blocks_manager_type::block_count_func func(blockman_);
01703
01704 if (block)
01705 {
01706 if ((nbit_left == 0) && (r == (bm::bits_in_block-1)))
01707 {
01708 if (block_count_arr)
01709 {
01710 count += block_count_arr[nblock_left];
01711 }
01712 else
01713 {
01714 func(block, nblock_left);
01715 }
01716 }
01717 else
01718 {
01719 if (left_gap)
01720 {
01721 count += gap_bit_count_range(BMGAP_PTR(block),
01722 (gap_word_t)nbit_left,
01723 (gap_word_t)r);
01724 }
01725 else
01726 {
01727 count += bit_block_calc_count_range(block, nbit_left, r);
01728 }
01729 }
01730 }
01731
01732 if (nblock_left == nblock_right)
01733 {
01734 return count + func.count();
01735 }
01736
01737 for (unsigned nb = nblock_left+1; nb < nblock_right; ++nb)
01738 {
01739 block = blockman_.get_block(nb);
01740 if (block_count_arr)
01741 {
01742 count += block_count_arr[nb];
01743 }
01744 else
01745 {
01746 if (block)
01747 func(block, nb);
01748 }
01749 }
01750 count += func.count();
01751
01752 block = blockman_.get_block(nblock_right);
01753 bool right_gap = BM_IS_GAP(blockman_, block, nblock_right);
01754
01755 if (block)
01756 {
01757 if (right_gap)
01758 {
01759 count += gap_bit_count_range(BMGAP_PTR(block),
01760 (gap_word_t)0,
01761 (gap_word_t)nbit_right);
01762 }
01763 else
01764 {
01765 count += bit_block_calc_count_range(block, 0, nbit_right);
01766 }
01767 }
01768
01769 return count;
01770 }
01771
01772
01773
01774 template<typename Alloc, typename MS>
01775 bvector<Alloc, MS>& bvector<Alloc, MS>::invert()
01776 {
01777 BMCOUNT_VALID(false)
01778 BM_SET_MMX_GUARD
01779
01780 bm::word_t*** blk_root = blockman_.get_rootblock();
01781 typename blocks_manager_type::block_invert_func func(blockman_);
01782 for_each_block(blk_root, blockman_.top_block_size(),
01783 bm::set_array_size, func);
01784 if (size_ == bm::id_max)
01785 {
01786 set_bit_no_check(bm::id_max, false);
01787 }
01788 else
01789 {
01790 set_range_no_check(size_, bm::id_max, false);
01791 }
01792
01793 return *this;
01794 }
01795
01796
01797
01798 template<typename Alloc, typename MS>
01799 bool bvector<Alloc, MS>::get_bit(bm::id_t n) const
01800 {
01801 BM_ASSERT(n < size_);
01802
01803
01804 unsigned nblock = unsigned(n >> bm::set_block_shift);
01805
01806 const bm::word_t* block = blockman_.get_block(nblock);
01807
01808 if (block)
01809 {
01810
01811 unsigned nbit = unsigned(n & bm::set_block_mask);
01812 unsigned is_set;
01813
01814 if (BM_IS_GAP(blockman_, block, nblock))
01815 {
01816 is_set = gap_test(BMGAP_PTR(block), nbit);
01817 }
01818 else
01819 {
01820 unsigned nword = unsigned(nbit >> bm::set_word_shift);
01821 nbit &= bm::set_word_mask;
01822
01823 is_set = (block[nword] & (((bm::word_t)1) << nbit));
01824 }
01825 return is_set != 0;
01826 }
01827 return false;
01828 }
01829
01830
01831
01832 template<typename Alloc, typename MS>
01833 void bvector<Alloc, MS>::optimize(bm::word_t* temp_block,
01834 optmode opt_mode,
01835 statistics* stat)
01836 {
01837 word_t*** blk_root = blockman_.blocks_root();
01838
01839 if (!temp_block)
01840 temp_block = blockman_.check_allocate_tempblock();
01841
01842 typename
01843 blocks_manager_type::block_opt_func opt_func(blockman_,
01844 temp_block,
01845 (int)opt_mode,
01846 stat);
01847 if (stat)
01848 {
01849 stat->bit_blocks = stat->gap_blocks
01850 = stat->max_serialize_mem
01851 = stat->memory_used
01852 = 0;
01853 ::memcpy(stat->gap_levels,
01854 blockman_.glen(), sizeof(gap_word_t) * bm::gap_levels);
01855 stat->max_serialize_mem = sizeof(id_t) * 4;
01856
01857 }
01858
01859 for_each_nzblock(blk_root, blockman_.effective_top_block_size(),
01860 bm::set_array_size, opt_func);
01861
01862 if (stat)
01863 {
01864 unsigned safe_inc = stat->max_serialize_mem / 10;
01865 if (!safe_inc) safe_inc = 256;
01866 stat->max_serialize_mem += safe_inc;
01867 stat->memory_used += sizeof(*this) - sizeof(blockman_);
01868 stat->memory_used += blockman_.mem_used();
01869 }
01870 }
01871
01872
01873
01874 template<typename Alloc, typename MS>
01875 void bvector<Alloc, MS>::optimize_gap_size()
01876 {
01877 struct bvector<Alloc, MS>::statistics st;
01878 calc_stat(&st);
01879
01880 if (!st.gap_blocks)
01881 return;
01882
01883 gap_word_t opt_glen[bm::gap_levels];
01884 ::memcpy(opt_glen, st.gap_levels, bm::gap_levels * sizeof(*opt_glen));
01885
01886 improve_gap_levels(st.gap_length,
01887 st.gap_length + st.gap_blocks,
01888 opt_glen);
01889
01890 set_gap_levels(opt_glen);
01891 }
01892
01893
01894
01895 template<typename Alloc, typename MS>
01896 void bvector<Alloc, MS>::set_gap_levels(const gap_word_t* glevel_len)
01897 {
01898 word_t*** blk_root = blockman_.blocks_root();
01899
01900 typename
01901 blocks_manager_type::gap_level_func gl_func(blockman_, glevel_len);
01902
01903 for_each_nzblock(blk_root, blockman_.top_block_size(),
01904 bm::set_array_size, gl_func);
01905
01906 blockman_.set_glen(glevel_len);
01907 }
01908
01909
01910
01911 template<typename Alloc, typename MS>
01912 int bvector<Alloc, MS>::compare(const bvector<Alloc, MS>& bvect) const
01913 {
01914 int res;
01915 unsigned bn = 0;
01916
01917 unsigned top_blocks = blockman_.effective_top_block_size();
01918 unsigned bvect_top_blocks = bvect.blockman_.effective_top_block_size();
01919
01920 if (bvect_top_blocks > top_blocks) top_blocks = bvect_top_blocks;
01921
01922 for (unsigned i = 0; i < top_blocks; ++i)
01923 {
01924 const bm::word_t* const* blk_blk = blockman_.get_topblock(i);
01925 const bm::word_t* const* arg_blk_blk =
01926 bvect.blockman_.get_topblock(i);
01927
01928 if (blk_blk == arg_blk_blk)
01929 {
01930 bn += bm::set_array_size;
01931 continue;
01932 }
01933
01934 for (unsigned j = 0; j < bm::set_array_size; ++j, ++bn)
01935 {
01936 const bm::word_t* arg_blk = arg_blk_blk ? arg_blk_blk[j] : 0;
01937 const bm::word_t* blk = blk_blk ? blk_blk[j] : 0;
01938 if (blk == arg_blk) continue;
01939
01940
01941
01942
01943 if (!blk || !arg_blk)
01944 {
01945 const bm::word_t* pblk;
01946 bool is_gap;
01947
01948 if (blk)
01949 {
01950 pblk = blk;
01951 res = 1;
01952 is_gap = BM_IS_GAP((*this), blk, bn);
01953 }
01954 else
01955 {
01956 pblk = arg_blk;
01957 res = -1;
01958 is_gap = BM_IS_GAP(bvect, arg_blk, bn);
01959 }
01960
01961 if (is_gap)
01962 {
01963 if (!gap_is_all_zero(BMGAP_PTR(pblk), bm::gap_max_bits))
01964 {
01965 return res;
01966 }
01967 }
01968 else
01969 {
01970 bm::wordop_t* blk1 = (wordop_t*)pblk;
01971 bm::wordop_t* blk2 =
01972 (wordop_t*)(pblk + bm::set_block_size);
01973 if (!bit_is_all_zero(blk1, blk2))
01974 {
01975 return res;
01976 }
01977 }
01978
01979 continue;
01980 }
01981
01982 bool arg_gap = BM_IS_GAP(bvect, arg_blk, bn);
01983 bool gap = BM_IS_GAP((*this), blk, bn);
01984
01985 if (arg_gap != gap)
01986 {
01987 bm::wordop_t temp_blk[bm::set_block_size_op];
01988 bm::wordop_t* blk1;
01989 bm::wordop_t* blk2;
01990
01991 if (gap)
01992 {
01993 gap_convert_to_bitset((bm::word_t*)temp_blk,
01994 BMGAP_PTR(blk));
01995
01996 blk1 = (bm::wordop_t*)temp_blk;
01997 blk2 = (bm::wordop_t*)arg_blk;
01998 }
01999 else
02000 {
02001 gap_convert_to_bitset((bm::word_t*)temp_blk,
02002 BMGAP_PTR(arg_blk));
02003
02004 blk1 = (bm::wordop_t*)blk;
02005 blk2 = (bm::wordop_t*)temp_blk;
02006
02007 }
02008 res = bitcmp(blk1, blk2, bm::set_block_size_op);
02009
02010 }
02011 else
02012 {
02013 if (gap)
02014 {
02015 res = gapcmp(BMGAP_PTR(blk), BMGAP_PTR(arg_blk));
02016 }
02017 else
02018 {
02019 res = bitcmp((bm::wordop_t*)blk,
02020 (bm::wordop_t*)arg_blk,
02021 bm::set_block_size_op);
02022 }
02023 }
02024
02025 if (res != 0)
02026 {
02027 return res;
02028 }
02029
02030
02031 }
02032
02033 }
02034
02035 return 0;
02036 }
02037
02038
02039
02040
02041 template<typename Alloc, typename MS>
02042 void bvector<Alloc, MS>::calc_stat(struct bvector<Alloc, MS>::statistics* st) const
02043 {
02044 st->bit_blocks = st->gap_blocks
02045 = st->max_serialize_mem
02046 = st->memory_used = 0;
02047
02048 ::memcpy(st->gap_levels,
02049 blockman_.glen(), sizeof(gap_word_t) * bm::gap_levels);
02050
02051 unsigned empty_blocks = 0;
02052 unsigned blocks_memory = 0;
02053 gap_word_t* gapl_ptr = st->gap_length;
02054
02055 st->max_serialize_mem = sizeof(id_t) * 4;
02056
02057 unsigned block_idx = 0;
02058
02059 unsigned top_size = blockman_.effective_top_block_size();
02060
02061 for (unsigned i = 0; i < top_size; ++i)
02062 {
02063 const bm::word_t* const* blk_blk = blockman_.get_topblock(i);
02064
02065 if (!blk_blk)
02066 {
02067 block_idx += bm::set_array_size;
02068 st->max_serialize_mem += sizeof(unsigned) + 1;
02069 continue;
02070 }
02071
02072 for (unsigned j = 0;j < bm::set_array_size; ++j, ++block_idx)
02073 {
02074 const bm::word_t* blk = blk_blk[j];
02075 if (IS_VALID_ADDR(blk))
02076 {
02077 st->max_serialize_mem += empty_blocks << 2;
02078 empty_blocks = 0;
02079
02080 if (BM_IS_GAP(blockman_, blk, block_idx))
02081 {
02082 ++(st->gap_blocks);
02083
02084 bm::gap_word_t* gap_blk = BMGAP_PTR(blk);
02085
02086 unsigned mem_used =
02087 bm::gap_capacity(gap_blk, blockman_.glen())
02088 * sizeof(gap_word_t);
02089
02090 *gapl_ptr = gap_length(gap_blk);
02091
02092 st->max_serialize_mem += *gapl_ptr * sizeof(gap_word_t);
02093 blocks_memory += mem_used;
02094
02095 ++gapl_ptr;
02096 }
02097 else
02098 {
02099 ++(st->bit_blocks);
02100 unsigned mem_used = sizeof(bm::word_t) * bm::set_block_size;
02101 st->max_serialize_mem += mem_used;
02102 blocks_memory += mem_used;
02103 }
02104 }
02105 else
02106 {
02107 ++empty_blocks;
02108 }
02109 }
02110 }
02111
02112 unsigned safe_inc = st->max_serialize_mem / 10;
02113 if (!safe_inc) safe_inc = 256;
02114 st->max_serialize_mem += safe_inc;
02115
02116
02117
02118 st->memory_used += sizeof(*this) - sizeof(blockman_);
02119 st->memory_used += blockman_.mem_used();
02120 st->memory_used += blocks_memory;
02121 }
02122
02123
02124
02125
02126
02127 template<class Alloc, class MS>
02128 bool bvector<Alloc, MS>::set_bit_no_check(bm::id_t n, bool val)
02129 {
02130
02131 unsigned nblock = unsigned(n >> bm::set_block_shift);
02132
02133 int block_type;
02134
02135 bm::word_t* blk =
02136 blockman_.check_allocate_block(nblock,
02137 val,
02138 get_new_blocks_strat(),
02139 &block_type);
02140
02141 if (!blk) return false;
02142
02143
02144 unsigned nbit = unsigned(n & bm::set_block_mask);
02145
02146 if (block_type == 1)
02147 {
02148 unsigned is_set;
02149 unsigned new_block_len;
02150
02151 new_block_len =
02152 gap_set_value(val, BMGAP_PTR(blk), nbit, &is_set);
02153 if (is_set)
02154 {
02155 BMCOUNT_ADJ(val)
02156
02157 unsigned threshold =
02158 bm::gap_limit(BMGAP_PTR(blk), blockman_.glen());
02159
02160 if (new_block_len > threshold)
02161 {
02162 extend_gap_block(nblock, BMGAP_PTR(blk));
02163 }
02164 return true;
02165 }
02166 }
02167 else
02168 {
02169 unsigned nword = unsigned(nbit >> bm::set_word_shift);
02170 nbit &= bm::set_word_mask;
02171
02172 bm::word_t* word = blk + nword;
02173 bm::word_t mask = (((bm::word_t)1) << nbit);
02174
02175 if (val)
02176 {
02177 if ( ((*word) & mask) == 0 )
02178 {
02179 *word |= mask;
02180 BMCOUNT_INC;
02181 return true;
02182 }
02183 }
02184 else
02185 {
02186 if ((*word) & mask)
02187 {
02188 *word &= ~mask;
02189 BMCOUNT_DEC;
02190 return true;
02191 }
02192 }
02193 }
02194 return false;
02195 }
02196
02197
02198
02199 template<class Alloc, class MS>
02200 bool bvector<Alloc, MS>::set_bit_conditional_impl(bm::id_t n,
02201 bool val,
02202 bool condition)
02203 {
02204
02205 unsigned nblock = unsigned(n >> bm::set_block_shift);
02206
02207 int block_type;
02208 bm::word_t* blk =
02209 blockman_.check_allocate_block(nblock,
02210 val,
02211 get_new_blocks_strat(),
02212 &block_type);
02213 if (!blk)
02214 return false;
02215
02216
02217 unsigned nbit = unsigned(n & bm::set_block_mask);
02218
02219 if (block_type == 1)
02220 {
02221 bm::gap_word_t* gap_blk = BMGAP_PTR(blk);
02222 bool old_val = (gap_test(gap_blk, nbit) != 0);
02223
02224 if (old_val != condition)
02225 {
02226 return false;
02227 }
02228
02229 if (val != old_val)
02230 {
02231 unsigned is_set;
02232 unsigned new_block_len =
02233 gap_set_value(val, gap_blk, nbit, &is_set);
02234 BM_ASSERT(is_set);
02235 BMCOUNT_ADJ(val)
02236
02237 unsigned threshold =
02238 bm::gap_limit(gap_blk, blockman_.glen());
02239 if (new_block_len > threshold)
02240 {
02241 extend_gap_block(nblock, gap_blk);
02242 }
02243 return true;
02244 }
02245 }
02246 else
02247 {
02248 unsigned nword = unsigned(nbit >> bm::set_word_shift);
02249 nbit &= bm::set_word_mask;
02250
02251 bm::word_t* word = blk + nword;
02252 bm::word_t mask = (((bm::word_t)1) << nbit);
02253 bool is_set = ((*word) & mask) != 0;
02254
02255 if (is_set != condition)
02256 {
02257 return false;
02258 }
02259 if (is_set != val)
02260 {
02261 if (val)
02262 {
02263 *word |= mask;
02264 BMCOUNT_INC;
02265 }
02266 else
02267 {
02268 *word &= ~mask;
02269 BMCOUNT_DEC;
02270 }
02271 return true;
02272 }
02273 }
02274 return false;
02275
02276 }
02277
02278
02279
02280
02281 template<class Alloc, class MS>
02282 bool bvector<Alloc, MS>::and_bit_no_check(bm::id_t n, bool val)
02283 {
02284
02285 unsigned nblock = unsigned(n >> bm::set_block_shift);
02286
02287 int block_type;
02288 bm::word_t* blk =
02289 blockman_.check_allocate_block(nblock,
02290 val,
02291 get_new_blocks_strat(),
02292 &block_type);
02293 if (!blk) return false;
02294
02295
02296 unsigned nbit = unsigned(n & bm::set_block_mask);
02297
02298 if (block_type == 1)
02299 {
02300 bm::gap_word_t* gap_blk = BMGAP_PTR(blk);
02301 bool old_val = (gap_test(gap_blk, nbit) != 0);
02302
02303 bool new_val = val & old_val;
02304 if (new_val != old_val)
02305 {
02306 unsigned is_set;
02307 unsigned new_block_len =
02308 gap_set_value(new_val, gap_blk, nbit, &is_set);
02309 BM_ASSERT(is_set);
02310 BMCOUNT_ADJ(val)
02311
02312 unsigned threshold =
02313 bm::gap_limit(gap_blk, blockman_.glen());
02314 if (new_block_len > threshold)
02315 {
02316 extend_gap_block(nblock, gap_blk);
02317 }
02318 return true;
02319 }
02320 }
02321 else
02322 {
02323 unsigned nword = unsigned(nbit >> bm::set_word_shift);
02324 nbit &= bm::set_word_mask;
02325
02326 bm::word_t* word = blk + nword;
02327 bm::word_t mask = (((bm::word_t)1) << nbit);
02328 bool is_set = ((*word) & mask) != 0;
02329
02330 bool new_val = is_set & val;
02331 if (new_val != val)
02332 {
02333 if (new_val)
02334 {
02335 *word |= mask;
02336 BMCOUNT_INC;
02337 }
02338 else
02339 {
02340 *word &= ~mask;
02341 BMCOUNT_DEC;
02342 }
02343 return true;
02344 }
02345 }
02346 return false;
02347 }
02348
02349
02350
02351
02352 template<class Alloc, class MS>
02353 bm::id_t bvector<Alloc, MS>::check_or_next(bm::id_t prev) const
02354 {
02355 for (;;)
02356 {
02357 unsigned nblock = unsigned(prev >> bm::set_block_shift);
02358 if (nblock >= bm::set_total_blocks)
02359 break;
02360
02361 if (blockman_.is_subblock_null(nblock >> bm::set_array_shift))
02362 {
02363 prev += (bm::set_blkblk_mask + 1) -
02364 (prev & bm::set_blkblk_mask);
02365 }
02366 else
02367 {
02368 unsigned nbit = unsigned(prev & bm::set_block_mask);
02369 int no_more_blocks;
02370 const bm::word_t* block =
02371 blockman_.get_block(nblock, &no_more_blocks);
02372
02373 if (no_more_blocks)
02374 {
02375 BM_ASSERT(block == 0);
02376 break;
02377 }
02378
02379 if (block)
02380 {
02381 if (IS_FULL_BLOCK(block)) return prev;
02382 if (BM_IS_GAP(blockman_, block, nblock))
02383 {
02384 if (bm::gap_find_in_block(BMGAP_PTR(block),
02385 nbit,
02386 &prev))
02387 {
02388 return prev;
02389 }
02390 }
02391 else
02392 {
02393 if (bm::bit_find_in_block(block, nbit, &prev))
02394 {
02395 return prev;
02396 }
02397 }
02398 }
02399 else
02400 {
02401 prev += (bm::set_block_mask + 1) -
02402 (prev & bm::set_block_mask);
02403 }
02404
02405 }
02406 if (!prev) break;
02407 }
02408
02409 return 0;
02410 }
02411
02412
02413
02414
02415 template<class Alloc, class MS>
02416 bm::id_t bvector<Alloc, MS>::check_or_next_extract(bm::id_t prev)
02417 {
02418 for (;;)
02419 {
02420 unsigned nblock = unsigned(prev >> bm::set_block_shift);
02421 if (nblock >= bm::set_total_blocks) break;
02422
02423 if (blockman_.is_subblock_null(nblock >> bm::set_array_shift))
02424 {
02425 prev += (bm::set_blkblk_mask + 1) -
02426 (prev & bm::set_blkblk_mask);
02427 }
02428 else
02429 {
02430 unsigned nbit = unsigned(prev & bm::set_block_mask);
02431
02432 int no_more_blocks;
02433 bm::word_t* block =
02434 blockman_.get_block(nblock, &no_more_blocks);
02435
02436 if (no_more_blocks)
02437 {
02438 BM_ASSERT(block == 0);
02439 break;
02440 }
02441
02442
02443 if (block)
02444 {
02445 if (IS_FULL_BLOCK(block))
02446 {
02447 set(prev, false);
02448 return prev;
02449 }
02450 if (BM_IS_GAP(blockman_, block, nblock))
02451 {
02452 unsigned is_set;
02453 unsigned new_block_len =
02454 gap_set_value(0, BMGAP_PTR(block), nbit, &is_set);
02455 if (is_set) {
02456 BMCOUNT_DEC
02457 unsigned threshold =
02458 bm::gap_limit(BMGAP_PTR(block), blockman_.glen());
02459 if (new_block_len > threshold)
02460 {
02461 extend_gap_block(nblock, BMGAP_PTR(block));
02462 }
02463 return prev;
02464 } else {
02465 if (bm::gap_find_in_block(BMGAP_PTR(block),
02466 nbit,
02467 &prev))
02468 {
02469 set(prev, false);
02470 return prev;
02471 }
02472 }
02473 }
02474 else
02475 {
02476 if (bm::bit_find_in_block(block, nbit, &prev))
02477 {
02478 BMCOUNT_DEC
02479
02480 unsigned nbit =
02481 unsigned(prev & bm::set_block_mask);
02482 unsigned nword =
02483 unsigned(nbit >> bm::set_word_shift);
02484 nbit &= bm::set_word_mask;
02485 bm::word_t* word = block + nword;
02486 bm::word_t mask = ((bm::word_t)1) << nbit;
02487 *word &= ~mask;
02488
02489 return prev;
02490 }
02491 }
02492 }
02493 else
02494 {
02495 prev += (bm::set_block_mask + 1) -
02496 (prev & bm::set_block_mask);
02497 }
02498
02499 }
02500 if (!prev) break;
02501 }
02502
02503 return 0;
02504 }
02505
02506
02507
02508 template<class Alloc, class MS>
02509 void bvector<Alloc, MS>::combine_operation(
02510 const bm::bvector<Alloc, MS>& bvect,
02511 bm::operation opcode)
02512 {
02513 typedef void (*block_bit_op)(bm::word_t*, const bm::word_t*);
02514 typedef void (*block_bit_op_next)(bm::word_t*,
02515 const bm::word_t*,
02516 bm::word_t*,
02517 const bm::word_t*);
02518
02519 unsigned top_blocks = blockman_.top_block_size();
02520 unsigned bvect_top_blocks = bvect.blockman_.top_block_size();
02521
02522 if (size_ == bvect.size_)
02523 {
02524 BM_ASSERT(top_blocks >= bvect_top_blocks);
02525 }
02526 else
02527 if (size_ < bvect.size_)
02528 {
02529 size_ = bvect.size_;
02530
02531 blockman_.reserve_top_blocks(bvect_top_blocks);
02532 top_blocks = blockman_.top_block_size();
02533 }
02534 else
02535 if (size_ > bvect.size_)
02536 {
02537 if (opcode == BM_AND)
02538 {
02539 set_range(bvect.size_, size_ - 1, false);
02540 if (bvect_top_blocks < top_blocks)
02541 {
02542
02543 top_blocks = bvect_top_blocks;
02544 }
02545 }
02546 }
02547
02548 bm::word_t*** blk_root = blockman_.blocks_root();
02549 unsigned block_idx = 0;
02550 unsigned i, j;
02551
02552 BM_SET_MMX_GUARD
02553
02554
02555 top_blocks = blockman_.effective_top_block_size();
02556 if (top_blocks < bvect.blockman_.effective_top_block_size())
02557 {
02558 if (opcode != BM_AND)
02559 {
02560 top_blocks = bvect.blockman_.effective_top_block_size();
02561 }
02562 }
02563
02564 for (i = 0; i < top_blocks; ++i)
02565 {
02566 bm::word_t** blk_blk = blk_root[i];
02567
02568 if (blk_blk == 0)
02569 {
02570 if (opcode == BM_AND)
02571 {
02572 block_idx += bm::set_array_size;
02573 continue;
02574 }
02575 const bm::word_t* const* bvbb = bvect.blockman_.get_topblock(i);
02576 if (bvbb == 0)
02577 {
02578 block_idx += bm::set_array_size;
02579 continue;
02580 }
02581
02582 for (j = 0; j < bm::set_array_size; ++j,++block_idx)
02583 {
02584 const bm::word_t* arg_blk =
02585 bvect.blockman_.get_block(i, j);
02586 if (arg_blk != 0)
02587 {
02588 bool arg_gap =
02589 BM_IS_GAP(bvect.blockman_, arg_blk, block_idx);
02590 combine_operation_with_block(block_idx, 0, 0,
02591 arg_blk, arg_gap,
02592 opcode);
02593 }
02594
02595 }
02596 continue;
02597 }
02598
02599 for (j = 0; j < bm::set_array_size; ++j, ++block_idx)
02600 {
02601 bm::word_t* blk = blk_blk[j];
02602 const bm::word_t* arg_blk = bvect.blockman_.get_block(i, j);
02603
02604 if (arg_blk || blk)
02605 {
02606 if (opcode == BM_AND)
02607 {
02608 if (!blk) continue;
02609 if (!arg_blk)
02610 {
02611 if (blk) blockman_.zero_block(block_idx);
02612 continue;
02613 }
02614 }
02615
02616 bool arg_gap = BM_IS_GAP(bvect.blockman_, arg_blk, block_idx);
02617 bool gap = BM_IS_GAP((*this).blockman_, blk, block_idx);
02618 combine_operation_with_block(block_idx, gap, blk,
02619 arg_blk, arg_gap,
02620 opcode);
02621 }
02622
02623 }
02624
02625 }
02626
02627 }
02628
02629
02630
02631
02632
02633 template<class Alloc, class MS>
02634 void
02635 bvector<Alloc, MS>::combine_operation_with_block(unsigned nb,
02636 unsigned gap,
02637 bm::word_t* blk,
02638 const bm::word_t* arg_blk,
02639 int arg_gap,
02640 bm::operation opcode)
02641 {
02642 if (!blk && arg_gap && (opcode == BM_OR || opcode == BM_XOR))
02643 {
02644 blk =
02645 blockman_.check_allocate_block(nb,
02646 0,
02647 BM_GAP,
02648 (int*)&gap,
02649 false );
02650 }
02651
02652 if (gap)
02653 {
02654 if (arg_gap)
02655 {
02656 gap_word_t tmp_buf[bm::gap_equiv_len * 3];
02657 gap_word_t* res;
02658 unsigned res_len;
02659
02660 gap_operation_func_type gfunc =
02661 operation_functions<true>::gap_operation(opcode);
02662 BM_ASSERT(gfunc);
02663 res = (*gfunc)(BMGAP_PTR(blk),
02664 BMGAP_PTR(arg_blk),
02665 tmp_buf,
02666 res_len);
02667 BM_ASSERT(res == tmp_buf);
02668 ++res_len;
02669
02670 BM_ASSERT(!(res == tmp_buf && res_len == 0));
02671
02672
02673
02674 if (gap_is_all_zero(res, bm::gap_max_bits))
02675 {
02676 blockman_.zero_block(nb);
02677 return;
02678 }
02679
02680
02681
02682 int level = gap_level(BMGAP_PTR(blk));
02683 unsigned threshold = blockman_.glen(level)-4;
02684 int new_level = gap_calc_level(res_len, blockman_.glen());
02685
02686 if (new_level == -1)
02687 {
02688 blockman_.convert_gap2bitset(nb, res);
02689 return;
02690 }
02691
02692 if (res_len > threshold)
02693 {
02694 set_gap_level(res, new_level);
02695 gap_word_t* new_blk =
02696 blockman_.allocate_gap_block(new_level, res);
02697
02698 bm::word_t* p = (bm::word_t*)new_blk;
02699 BMSET_PTRGAP(p);
02700
02701 blockman_.set_block_ptr(nb, p);
02702 blockman_.get_allocator().free_gap_block(BMGAP_PTR(blk),
02703 blockman_.glen());
02704 return;
02705 }
02706
02707
02708
02709
02710 set_gap_level(tmp_buf, level);
02711 ::memcpy(BMGAP_PTR(blk), tmp_buf, res_len * sizeof(gap_word_t));
02712 return;
02713 }
02714 else
02715 {
02716
02717
02718
02719 if (arg_blk == 0)
02720 {
02721 switch (opcode)
02722 {
02723 case BM_AND:
02724 blockman_.zero_block(nb);
02725 return;
02726 case BM_OR: case BM_SUB: case BM_XOR:
02727 return;
02728 }
02729 }
02730 gap_word_t* gap_blk = BMGAP_PTR(blk);
02731 if (opcode == BM_AND)
02732 {
02733 unsigned gap_cnt = gap_bit_count(gap_blk);
02734 if (gap_cnt < 128)
02735 {
02736 gap_word_t tmp_buf[bm::gap_equiv_len * 3];
02737 gap_word_t arr_len =
02738 gap_convert_to_arr(tmp_buf, gap_blk,
02739 bm::gap_equiv_len-10);
02740 BM_ASSERT(gap_cnt == arr_len);
02741 blockman_.zero_block(nb);
02742 unsigned arr_i = 0;
02743 int block_type;
02744 blk =
02745 blockman_.check_allocate_block(nb,
02746 true,
02747 BM_GAP,
02748 &block_type,
02749 false
02750 );
02751 BM_ASSERT(block_type==1);
02752 gap_blk = BMGAP_PTR(blk);
02753 unsigned threshold = bm::gap_limit(gap_blk, blockman_.glen());
02754 for (; arr_i < arr_len; ++arr_i)
02755 {
02756 gap_word_t bit_idx = tmp_buf[arr_i];
02757 if (bm::test_bit(arg_blk, bit_idx))
02758 {
02759 unsigned is_set;
02760 unsigned new_block_len =
02761 gap_set_value(true, gap_blk, bit_idx, &is_set);
02762 BM_ASSERT(is_set);
02763 if (new_block_len > threshold)
02764 {
02765 gap_blk =
02766 blockman_.extend_gap_block(nb, gap_blk);
02767 if (gap_blk == 0)
02768 {
02769 blk = blockman_.check_allocate_block(
02770 nb,
02771 true,
02772 this->get_new_blocks_strat(),
02773 &block_type,
02774 false
02775 );
02776 BM_ASSERT(block_type == 0);
02777
02778 for (++arr_i; arr_i < arr_len; ++arr_i)
02779 {
02780 bit_idx = tmp_buf[arr_i];
02781 if (bm::test_bit(arg_blk, bit_idx))
02782 {
02783 or_bit_block(blk, bit_idx, 1);
02784 }
02785 }
02786 return;
02787 }
02788 }
02789 }
02790 }
02791
02792 return;
02793 }
02794 }
02795
02796 blk = blockman_.convert_gap2bitset(nb, gap_blk);
02797 }
02798 }
02799 else
02800 {
02801 if (arg_gap)
02802 {
02803 if (IS_VALID_ADDR(blk))
02804 {
02805
02806
02807 gap_operation_to_bitset_func_type gfunc =
02808 operation_functions<true>::gap_op_to_bit(opcode);
02809 BM_ASSERT(gfunc);
02810 (*gfunc)(blk, BMGAP_PTR(arg_blk));
02811 return;
02812 }
02813
02814
02815
02816 gap_word_t* temp_blk = (gap_word_t*) blockman_.check_allocate_tempblock();
02817 arg_blk =
02818 gap_convert_to_bitset_smart((bm::word_t*)temp_blk,
02819 BMGAP_PTR(arg_blk),
02820 bm::gap_max_bits);
02821
02822 }
02823 }
02824
02825
02826 bm::word_t* dst = blk;
02827
02828 bm::word_t* ret;
02829 if (dst == 0 && arg_blk == 0)
02830 {
02831 return;
02832 }
02833
02834 switch (opcode)
02835 {
02836 case BM_AND:
02837 ret = bit_operation_and(dst, arg_blk);
02838 goto copy_block;
02839 case BM_XOR:
02840 ret = bit_operation_xor(dst, arg_blk);
02841 if (ret && (ret == arg_blk) && IS_FULL_BLOCK(dst))
02842 {
02843 ret = blockman_.get_allocator().alloc_bit_block();
02844 #ifdef BMVECTOPT
02845 VECT_XOR_ARR_2_MASK(ret,
02846 arg_blk,
02847 arg_blk + bm::set_block_size,
02848 bm::all_bits_mask);
02849 #else
02850 bm::wordop_t* dst_ptr = (wordop_t*)ret;
02851 const bm::wordop_t* wrd_ptr = (wordop_t*) arg_blk;
02852 const bm::wordop_t* wrd_end =
02853 (wordop_t*) (arg_blk + bm::set_block_size);
02854
02855 do
02856 {
02857 dst_ptr[0] = bm::all_bits_mask ^ wrd_ptr[0];
02858 dst_ptr[1] = bm::all_bits_mask ^ wrd_ptr[1];
02859 dst_ptr[2] = bm::all_bits_mask ^ wrd_ptr[2];
02860 dst_ptr[3] = bm::all_bits_mask ^ wrd_ptr[3];
02861
02862 dst_ptr+=4;
02863 wrd_ptr+=4;
02864
02865 } while (wrd_ptr < wrd_end);
02866 #endif
02867 break;
02868 }
02869 goto copy_block;
02870 case BM_OR:
02871 ret = bit_operation_or(dst, arg_blk);
02872 copy_block:
02873 if (ret && (ret == arg_blk) && !IS_FULL_BLOCK(ret))
02874 {
02875 ret = blockman_.get_allocator().alloc_bit_block();
02876 bit_block_copy(ret, arg_blk);
02877 }
02878 break;
02879
02880 case BM_SUB:
02881 ret = bit_operation_sub(dst, arg_blk);
02882 if (ret && ret == arg_blk)
02883 {
02884 ret = blockman_.get_allocator().alloc_bit_block();
02885 #ifdef BMVECTOPT
02886 VECT_ANDNOT_ARR_2_MASK(ret,
02887 arg_blk,
02888 arg_blk + bm::set_block_size,
02889 bm::all_bits_mask);
02890 #else
02891
02892 bm::wordop_t* dst_ptr = (wordop_t*)ret;
02893 const bm::wordop_t* wrd_ptr = (wordop_t*) arg_blk;
02894 const bm::wordop_t* wrd_end =
02895 (wordop_t*) (arg_blk + bm::set_block_size);
02896
02897 do
02898 {
02899 dst_ptr[0] = bm::all_bits_mask & ~wrd_ptr[0];
02900 dst_ptr[1] = bm::all_bits_mask & ~wrd_ptr[1];
02901 dst_ptr[2] = bm::all_bits_mask & ~wrd_ptr[2];
02902 dst_ptr[3] = bm::all_bits_mask & ~wrd_ptr[3];
02903
02904 dst_ptr+=4;
02905 wrd_ptr+=4;
02906
02907 } while (wrd_ptr < wrd_end);
02908 #endif
02909 }
02910 break;
02911 default:
02912 BM_ASSERT(0);
02913 ret = 0;
02914 }
02915
02916 if (ret != dst)
02917 {
02918 blockman_.set_block(nb, ret);
02919 blockman_.get_allocator().free_bit_block(dst);
02920 }
02921 }
02922
02923
02924
02925 template<class Alloc, class MS>
02926 void bvector<Alloc, MS>::set_range_no_check(bm::id_t left,
02927 bm::id_t right,
02928 bool value)
02929 {
02930
02931 unsigned nblock_left = unsigned(left >> bm::set_block_shift);
02932 unsigned nblock_right = unsigned(right >> bm::set_block_shift);
02933
02934 bm::word_t* block = blockman_.get_block(nblock_left);
02935 bool left_gap = BM_IS_GAP(blockman_, block, nblock_left);
02936
02937 unsigned nbit_left = unsigned(left & bm::set_block_mask);
02938 unsigned nbit_right = unsigned(right & bm::set_block_mask);
02939
02940 unsigned r =
02941 (nblock_left == nblock_right) ? nbit_right :(bm::bits_in_block-1);
02942
02943 bm::gap_word_t tmp_gap_blk[5] = {0,};
02944
02945
02946
02947 unsigned nb;
02948 if ((nbit_left == 0) && (r == bm::bits_in_block - 1))
02949 {
02950 nb = nblock_left;
02951 }
02952 else
02953 {
02954 gap_init_range_block(tmp_gap_blk,
02955 nbit_left, r, value, bm::bits_in_block);
02956
02957 combine_operation_with_block(nblock_left,
02958 left_gap,
02959 block,
02960 (bm::word_t*) tmp_gap_blk,
02961 1,
02962 value ? BM_OR : BM_AND);
02963
02964 if (nblock_left == nblock_right)
02965 return;
02966 nb = nblock_left+1;
02967 }
02968
02969
02970
02971 unsigned nb_to = nblock_right + (nbit_right ==(bm::bits_in_block-1));
02972
02973 if (value)
02974 {
02975 for (; nb < nb_to; ++nb)
02976 {
02977 block = blockman_.get_block(nb);
02978 if (IS_FULL_BLOCK(block))
02979 continue;
02980
02981 bool is_gap = BM_IS_GAP(blockman_, block, nb);
02982
02983 blockman_.set_block(nb, FULL_BLOCK_ADDR);
02984 blockman_.set_block_bit(nb);
02985
02986 if (is_gap)
02987 {
02988 blockman_.get_allocator().free_gap_block(BMGAP_PTR(block),
02989 blockman_.glen());
02990 }
02991 else
02992 {
02993 blockman_.get_allocator().free_bit_block(block);
02994 }
02995
02996 }
02997 }
02998 else
02999 {
03000 for (; nb < nb_to; ++nb)
03001 {
03002 block = blockman_.get_block(nb);
03003 if (block == 0)
03004 continue;
03005 bool is_gap = BM_IS_GAP(blockman_, block, nb);
03006 blockman_.set_block(nb, 0, false );
03007
03008
03009 if (is_gap)
03010 {
03011 blockman_.get_allocator().free_gap_block(BMGAP_PTR(block),
03012 blockman_.glen());
03013 }
03014 else
03015 {
03016 blockman_.get_allocator().free_bit_block(block);
03017 }
03018
03019 }
03020 }
03021
03022 if (nb_to > nblock_right)
03023 return;
03024
03025 block = blockman_.get_block(nblock_right);
03026 bool right_gap = BM_IS_GAP(blockman_, block, nblock_right);
03027
03028 gap_init_range_block(tmp_gap_blk,
03029 0, nbit_right, value, bm::bits_in_block);
03030
03031 combine_operation_with_block(nblock_right,
03032 right_gap,
03033 block,
03034 (bm::word_t*) tmp_gap_blk,
03035 1,
03036 value ? BM_OR : BM_AND);
03037
03038 }
03039
03040
03041
03042
03043 }
03044
03045 #include "bmundef.h"
03046
03047 #ifdef _MSC_VER
03048 #pragma warning( default : 4311 4312)
03049 #endif
03050
03051
03052 #endif
03053
03054