bm.h
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:121k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: bm.h,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:39:05  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*
  10. Copyright (c) 2002,2003 Anatoliy Kuznetsov.
  11. Permission is hereby granted, free of charge, to any person 
  12. obtaining a copy of this software and associated documentation 
  13. files (the "Software"), to deal in the Software without restriction, 
  14. including without limitation the rights to use, copy, modify, merge, 
  15. publish, distribute, sublicense, and/or sell copies of the Software, 
  16. and to permit persons to whom the Software is furnished to do so, 
  17. subject to the following conditions:
  18. The above copyright notice and this permission notice shall be included 
  19. in all copies or substantial portions of the Software.
  20. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
  21. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
  22. OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
  23. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
  24. DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
  25. ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
  26. OTHER DEALINGS IN THE SOFTWARE.
  27. */
  28. #ifndef BM__H__INCLUDED__
  29. #define BM__H__INCLUDED__
  30. #include <string.h>
  31. #include <assert.h>
  32. #include <limits.h>
  33. // define BM_NO_STL if you use BM in "STL free" environment and want
  34. // to disable any references to STL headers
  35. #ifndef BM_NO_STL
  36. # include <iterator>
  37. #endif
  38. #include "bmconst.h"
  39. #include "bmdef.h"
  40. // Vector based optimizations are incompatible with 64-bit optimization
  41. // which is considered a form of vectorization
  42. #ifdef BMSSE2OPT
  43. # undef BM64OPT
  44. # define BMVECTOPT
  45. # include "bmsse2.h"
  46. #endif
  47. #include "bmfwd.h"
  48. #include "bmfunc.h"
  49. #include "bmvmin.h"
  50. #include "encoding.h"
  51. #include "bmalloc.h"
  52. namespace bm
  53. {
  54. #ifdef BMCOUNTOPT
  55. # define BMCOUNT_INC ++count_;
  56. # define BMCOUNT_DEC --count_;
  57. # define BMCOUNT_VALID(x) count_is_valid_ = x;
  58. # define BMCOUNT_SET(x) count_ = x; count_is_valid_ = true;
  59. # define BMCOUNT_ADJ(x) if (x) ++count_; else --count_;
  60. #else
  61. # define BMCOUNT_INC
  62. # define BMCOUNT_DEC
  63. # define BMCOUNT_VALID(x)
  64. # define BMCOUNT_SET(x)
  65. # define BMCOUNT_ADJ(x)
  66. #endif
  67. // Serialization related constants
  68. const unsigned char set_block_end   = 0;   //!< End of serialization
  69. const unsigned char set_block_1zero = 1;   //!< One all-zero block
  70. const unsigned char set_block_1one  = 2;   //!< One block all-set (1111...)
  71. const unsigned char set_block_8zero = 3;   //!< Up to 256 zero blocks
  72. const unsigned char set_block_8one  = 4;   //!< Up to 256 all-set blocks
  73. const unsigned char set_block_16zero= 5;   //!< Up to 65536 zero blocks
  74. const unsigned char set_block_16one = 6;   //!< UP to 65536 all-set blocks
  75. const unsigned char set_block_32zero= 7;   //!< Up to 4G zero blocks
  76. const unsigned char set_block_32one = 8;   //!< UP to 4G all-set blocks
  77. const unsigned char set_block_azero = 9;   //!< All other blocks zero
  78. const unsigned char set_block_aone  = 10;  //!< All other blocks one
  79. const unsigned char set_block_bit     = 11;  //!< Plain bit block
  80. const unsigned char set_block_sgapbit = 12;  //!< SGAP compressed bitblock
  81. const unsigned char set_block_sgapgap = 13;  //!< SGAP compressed GAP block
  82. const unsigned char set_block_gap     = 14;  //!< Plain GAP block
  83. const unsigned char set_block_gapbit  = 15;  //!< GAP compressed bitblock 
  84. const unsigned char set_block_arrbit  = 16;  //!< List of bits ON
  85. #define SER_NEXT_GRP(enc, nb, B_1ZERO, B_8ZERO, B_16ZERO, B_32ZERO) 
  86.    if (nb == 1) 
  87.       enc.put_8(B_1ZERO); 
  88.    else if (nb < 256) 
  89.    { 
  90.       enc.put_8(B_8ZERO); 
  91.       enc.put_8((unsigned char)nb); 
  92.    } 
  93.    else if (nb < 65536) 
  94.    { 
  95.       enc.put_8(B_16ZERO); 
  96.       enc.put_16((unsigned short)nb); 
  97.    } 
  98.    else 
  99.    {
  100.       enc.put_8(B_32ZERO); 
  101.       enc.put_32(nb); 
  102.    }
  103. #define BM_SET_ONE_BLOCKS(x) 
  104.     {
  105.          unsigned end_block = i + x; 
  106.          for (;i < end_block; ++i) 
  107.             blockman_.set_block_all_set(i); 
  108.     } 
  109.     --i
  110. typedef bm::miniset<bm::block_allocator, bm::set_total_blocks> mem_save_set;
  111. /** @defgroup bvector The Main bvector<> Group
  112.  *  This is the main group. It includes bvector template: front end of the bm library.
  113.  *  
  114.  */
  115. /*!
  116.    @brief Block allocation strategies.
  117.    @ingroup bvector
  118. */
  119. enum strategy
  120. {
  121.     BM_BIT = 0, //!< No GAP compression strategy. All new blocks are bit blocks.
  122.     BM_GAP = 1  //!< GAP compression is ON.
  123. };
  124. /*!
  125.    @brief bitvector with runtime compression of bits.
  126.    @ingroup bvector
  127. */
  128. template<class A, class MS> 
  129. class bvector
  130. {
  131. public:
  132.     /*!
  133.        @brief Structure with statistical information about bitset's memory 
  134.               allocation details. 
  135.        @ingroup bvector
  136.     */
  137.     struct statistics
  138.     {
  139.         /// Number of bit blocks.
  140.         unsigned bit_blocks; 
  141.         /// Number of GAP blocks.
  142.         unsigned gap_blocks;  
  143.         /// Estimated maximum of memory required for serialization.
  144.         unsigned max_serialize_mem;
  145.         /// Memory used by bitvector including temp and service blocks
  146.         unsigned  memory_used;
  147.         /// Array of all GAP block lengths in the bvector.
  148.         gap_word_t   gap_length[bm::set_total_blocks];
  149.         /// GAP lengths used by bvector
  150.         gap_word_t  gap_levels[bm::gap_levels];
  151.     };
  152.     /**
  153.         @brief Class reference implements an object for bit assignment.
  154.         Since C++ does not provide with build-in bit type supporting l-value 
  155.         operations we have to emulate it.
  156.         @ingroup bvector
  157.     */
  158.     class reference
  159.     {
  160.     public:
  161.         reference(bvector<A, MS>& bv, bm::id_t position) :bv_(bv),position_(position)
  162.         {}
  163.         reference(const reference& ref): bv_(ref.bv_), position_(ref.position_)
  164.         {
  165.             bv_.set(position_, ref.bv_.get_bit(position_));
  166.         }
  167.         
  168.         operator bool() const
  169.         {
  170.             return bv_.get_bit(position_);
  171.         }
  172.         const reference& operator=(const reference& ref) const
  173.         {
  174.             bv_.set(position_, (bool)ref);
  175.             return *this;
  176.         }
  177.         const reference& operator=(bool value) const
  178.         {
  179.             bv_.set(position_, value);
  180.             return *this;
  181.         }
  182.         bool operator==(const reference& ref) const
  183.         {
  184.             return bool(*this) == bool(ref);
  185.         }
  186.         /*! Bitwise AND. Performs operation: bit = bit AND value */
  187.         const reference& operator&=(bool value) const
  188.         {
  189.             bv_.set(position_, value);
  190.             return *this;
  191.         }
  192.         /*! Bitwise OR. Performs operation: bit = bit OR value */
  193.         const reference& operator|=(bool value) const
  194.         {
  195.             if (value != bv_.get_bit(position_))
  196.             {
  197.                 bv_.set_bit(position_);
  198.             }
  199.             return *this;
  200.         }
  201.         /*! Bitwise exclusive-OR (XOR). Performs operation: bit = bit XOR value */
  202.         const reference& operator^=(bool value) const
  203.         {
  204.             bv_.set(position_, value != bv_.get_bit(position_));
  205.             return *this;
  206.         }
  207.         /*! Logical Not operator */
  208.         bool operator!() const
  209.         {
  210.             return !bv_.get_bit(position_);
  211.         }
  212.         /*! Bit Not operator */
  213.         bool operator~() const
  214.         {
  215.             return !bv_.get_bit(position_);
  216.         }
  217.         /*! Negates the bit value */
  218.         reference& flip()
  219.         {
  220.             bv_.flip(position_);
  221.             return *this;
  222.         }
  223.     private:
  224.         bvector<A, MS>& bv_;       //!< Reference variable on parent bitvector.
  225.         bm::id_t        position_; //!< Position in parent bitvector.
  226.     };
  227.     typedef bool const_reference;
  228.     /*!
  229.         @brief Base class for all iterators.
  230.         @ingroup bvector
  231.     */
  232.     class iterator_base
  233.     {
  234.     friend class bvector;
  235.     public:
  236.         iterator_base() : block_(0) {}
  237.         bool operator==(const iterator_base& it) const
  238.         {
  239.             return (position_ == it.position_) && (bv_ == it.bv_);
  240.         }
  241.         bool operator!=(const iterator_base& it) const
  242.         {
  243.             return ! operator==(it);
  244.         }
  245.         bool operator < (const iterator_base& it) const
  246.         {
  247.             return position_ < it.position_;
  248.         }
  249.         bool operator <= (const iterator_base& it) const
  250.         {
  251.             return position_ <= it.position_;
  252.         }
  253.         bool operator > (const iterator_base& it) const
  254.         {
  255.             return position_ > it.position_;
  256.         }
  257.         bool operator >= (const iterator_base& it) const
  258.         {
  259.             return position_ >= it.position_;
  260.         }
  261.         /**
  262.            fn bool bm::bvector::iterator_base::valid() const
  263.            brief Checks if iterator is still valid. Analog of != 0 comparison for pointers.
  264.            returns true if iterator is valid.
  265.         */
  266.         bool valid() const
  267.         {
  268.             return position_ != bm::id_max;
  269.         }
  270.         /**
  271.            fn bool bm::bvector::iterator_base::invalidate() 
  272.            brief Turns iterator into an invalid state.
  273.         */
  274.         void invalidate()
  275.         {
  276.             position_ = bm::id_max;
  277.         }
  278.     public:
  279.         /** Information about current bitblock. */
  280.         struct bitblock_descr
  281.         {
  282.             const bm::word_t*   ptr;      //!< Word pointer.
  283.             unsigned            bits[32]; //!< Unpacked list of ON bits
  284.             unsigned            idx;      //!< Current position in the bit list
  285.             unsigned            cnt;      //!< Number of ON bits
  286.             bm::id_t            pos;      //!< Last bit position before 
  287.         };
  288.         /** Information about current DGAP block. */
  289.         struct dgap_descr
  290.         {
  291.             const gap_word_t*   ptr;       //!< Word pointer.
  292.             gap_word_t          gap_len;   //!< Current dgap length.
  293.         };
  294.     protected:
  295.         bm::bvector<A, MS>*   bv_;         //!< Pointer on parent bitvector.
  296.         bm::id_t              position_;   //!< Bit position (bit number) in the bitvector.
  297.         const bm::word_t*     block_;      //!< Block pointer. If NULL iterator is considered invalid.
  298.         unsigned              block_type_; //!< Type of the current block. 0 - Bit, 1 - GAP
  299.         unsigned              block_idx_;  //!< Block index.
  300.         /*! Block type dependent information for current block. */
  301.         union block_descr
  302.         {
  303.             bitblock_descr   bit_;  //!< BitBlock related info.
  304.             dgap_descr       gap_;  //!< DGAP block related info.
  305.         } bdescr_;
  306.     };
  307.     /*!
  308.         @brief Output iterator iterator designed to set "ON" bits based on
  309.         their indeces.
  310.         STL container can be converted to bvector using this iterator
  311.         @ingroup bvector
  312.     */
  313.     class insert_iterator
  314.     {
  315.     public:
  316. #ifndef BM_NO_STL
  317.         typedef std::output_iterator_tag  iterator_category;
  318. #endif
  319.         typedef unsigned value_type;
  320.         typedef void difference_type;
  321.         typedef void pointer;
  322.         typedef void reference;
  323.         insert_iterator(bvector<A, MS>& bvect)
  324.          : bvect_(bvect)
  325.         {}
  326.         
  327.         insert_iterator& operator=(bm::id_t n)
  328.         {
  329.             bvect_.set(n);
  330.             return *this;
  331.         }
  332.         
  333.         /*! Returns *this without doing nothing */
  334.         insert_iterator& operator*() { return *this; }
  335.         /*! Returns *this. This iterator does not move */
  336.         insert_iterator& operator++() { return *this; }
  337.         /*! Returns *this. This iterator does not move */
  338.         insert_iterator& operator++(int) { return *this; }
  339.         
  340.     protected:
  341.         bm::bvector<A, MS>&   bvect_;
  342.     };
  343.     /*!
  344.         @brief Constant input iterator designed to enumerate "ON" bits
  345.         @ingroup bvector
  346.     */
  347.     class enumerator : public iterator_base
  348.     {
  349.     public:
  350. #ifndef BM_NO_STL
  351.         typedef std::input_iterator_tag  iterator_category;
  352. #endif
  353.         typedef unsigned value_type;
  354.         typedef unsigned difference_type;
  355.         typedef unsigned* pointer;
  356.         typedef unsigned& reference;
  357.     public:
  358.         enumerator() : iterator_base() {}
  359.         enumerator(const bvector* bvect, int position)
  360.             : iterator_base()
  361.         { 
  362.             this->bv_ = const_cast<bvector<A, MS>*>(bvect);
  363.             if (position == 0)
  364.             {
  365.                 go_first();
  366.             }
  367.             else
  368.             {
  369.                 this->invalidate();
  370.             }
  371.         }
  372.         bm::id_t operator*() const
  373.         { 
  374.             return this->position_; 
  375.         }
  376.         enumerator& operator++()
  377.         {
  378.             go_up();
  379.             return *this;
  380.         }
  381.         enumerator operator++(int)
  382.         {
  383.             enumerator tmp = *this;
  384.             go_up();
  385.             return tmp;
  386.         }
  387.         void go_first()
  388.         {
  389.             BM_ASSERT(this->bv_);
  390.         #ifdef BMCOUNTOPT
  391.             if (this->bv_->count_is_valid_ && 
  392.                 this->bv_->count_ == 0)
  393.             {
  394.                 this->invalidate();
  395.                 return;
  396.             }
  397.         #endif
  398.             typename bm::bvector<A, MS>::blocks_manager* bman
  399.                 = &this->bv_->blockman_;
  400.             bm::word_t*** blk_root = bman->blocks_root();
  401.             this->block_idx_ = this->position_= 0;
  402.             unsigned i, j;
  403.             for (i = 0; i < bman->top_block_size(); ++i)
  404.             {
  405.                 bm::word_t** blk_blk = blk_root[i];
  406.                 if (blk_blk == 0) // not allocated
  407.                 {
  408.                     this->block_idx_ += bm::set_array_size;
  409.                     this->position_  += bm::bits_in_array;
  410.                     continue;
  411.                 }
  412.                 for (j = 0; j < bm::set_array_size; ++j, ++this->block_idx_)
  413.                 {
  414.                     this->block_ = blk_blk[j];
  415.                     if (this->block_ == 0)
  416.                     {
  417.                         this->position_ += bits_in_block;
  418.                         continue;
  419.                     }
  420.                     if (BM_IS_GAP((*bman), this->block_, this->block_idx_))
  421.                     {
  422.                         this->block_type_ = 1;
  423.                         if (search_in_gapblock())
  424.                         {
  425.                             return;
  426.                         }
  427.                     }
  428.                     else
  429.                     {
  430.                         this->block_type_ = 0;
  431.                         if (search_in_bitblock())
  432.                         {
  433.                             return;
  434.                         }
  435.                     }
  436.             
  437.                 } // for j
  438.             } // for i
  439.             this->invalidate();
  440.         }
  441.         void go_up()
  442.         {
  443.             // Current block search.
  444.             ++this->position_;
  445.             switch (this->block_type_)
  446.             {
  447.             case 0:   //  BitBlock
  448.                 {
  449.                 // check if we can get the value from the 
  450.                 // bits cache
  451.                 unsigned idx = ++this->bdescr_.bit_.idx;
  452.                 if (idx < this->bdescr_.bit_.cnt)
  453.                 {
  454.                     this->position_ = this->bdescr_.bit_.pos
  455.                         + this->bdescr_.bit_.bits[idx];
  456.                     return; 
  457.                 }
  458.                 this->position_ += 31 - this->bdescr_.bit_.bits[--idx];
  459.                 const bm::word_t* pend = this->block_ + bm::set_block_size;
  460.                 while (++this->bdescr_.bit_.ptr < pend)
  461.                 {
  462.                     bm::word_t w = *this->bdescr_.bit_.ptr;
  463.                     if (w)
  464.                     {
  465.                         this->bdescr_.bit_.idx = 0;
  466.                         this->bdescr_.bit_.pos = this->position_;
  467.                         this->bdescr_.bit_.cnt
  468.                             = bm::bit_list(w, this->bdescr_.bit_.bits); 
  469.                         this->position_ += this->bdescr_.bit_.bits[0];
  470.                         return;
  471.                     }
  472.                     else
  473.                     {
  474.                         this->position_ += 32;
  475.                     }
  476.                 }
  477.     
  478.                 }
  479.                 break;
  480.             case 1:   // DGAP Block
  481.                 {
  482.                     if (--this->bdescr_.gap_.gap_len)
  483.                     {
  484.                         return;
  485.                     }
  486.                     // next gap is "OFF" by definition.
  487.                     if (*this->bdescr_.gap_.ptr == bm::gap_max_bits - 1)
  488.                     {
  489.                         break;
  490.                     }
  491.                     gap_word_t prev = *this->bdescr_.gap_.ptr;
  492.                     register unsigned val = *(++this->bdescr_.gap_.ptr);
  493.                     this->position_ += val - prev;
  494.                     // next gap is now "ON"
  495.                     if (*this->bdescr_.gap_.ptr == bm::gap_max_bits - 1)
  496.                     {
  497.                         break;
  498.                     }
  499.                     prev = *this->bdescr_.gap_.ptr;
  500.                     val = *(++this->bdescr_.gap_.ptr);
  501.                     this->bdescr_.gap_.gap_len = val - prev;
  502.                     return;  // next "ON" found;
  503.                 }
  504.             default:
  505.                 assert(0);
  506.             } // switch
  507.             // next bit not present in the current block
  508.             // keep looking in the next blocks.
  509.             ++this->block_idx_;
  510.             unsigned i = this->block_idx_ >> bm::set_array_shift;
  511.             for (; i < this->bv_->blockman_.top_block_size(); ++i)
  512.             {
  513.                 bm::word_t** blk_blk = this->bv_->blockman_.blocks_[i];
  514.                 if (blk_blk == 0)
  515.                 {
  516.                     this->block_idx_ += bm::set_array_size;
  517.                     this->position_ += bm::bits_in_array;
  518.                     continue;
  519.                 }
  520.                 unsigned j = this->block_idx_ & bm::set_array_mask;
  521.                 for(; j < bm::set_array_size; ++j, ++this->block_idx_)
  522.                 {
  523.                     this->block_ = blk_blk[j];
  524.                     if (this->block_ == 0)
  525.                     {
  526.                         this->position_ += bm::bits_in_block;
  527.                         continue;
  528.                     }
  529.                     if (BM_IS_GAP((this->bv_->blockman_), this->block_, 
  530.                                   this->block_idx_))
  531.                     {
  532.                         this->block_type_ = 1;
  533.                         if (search_in_gapblock())
  534.                         {
  535.                             return;
  536.                         }
  537.                     }
  538.                     else
  539.                     {
  540.                         this->block_type_ = 0;
  541.                         if (search_in_bitblock())
  542.                         {
  543.                             return;
  544.                         }
  545.                     }
  546.             
  547.                 } // for j
  548.             } // for i
  549.             this->invalidate();
  550.         }
  551.     private:
  552.         bool search_in_bitblock()
  553.         {
  554.             assert(this->block_type_ == 0);
  555.             // now lets find the first bit in block.
  556.             this->bdescr_.bit_.ptr = this->block_;
  557.             const word_t* ptr_end = this->block_ + bm::set_block_size;
  558.             do
  559.             {
  560.                 register bm::word_t w = *this->bdescr_.bit_.ptr;
  561.                 if (w)  
  562.                 {
  563.                     this->bdescr_.bit_.idx = 0;
  564.                     this->bdescr_.bit_.pos = this->position_;
  565.                     this->bdescr_.bit_.cnt
  566.                         = bm::bit_list(w, this->bdescr_.bit_.bits); 
  567.                     this->position_ += this->bdescr_.bit_.bits[0];
  568.                     return true;
  569.                 }
  570.                 else
  571.                 {
  572.                     this->position_ += 32;
  573.                 }
  574.             } 
  575.             while (++this->bdescr_.bit_.ptr < ptr_end);
  576.             return false;
  577.         }
  578.         bool search_in_gapblock()
  579.         {
  580.             assert(this->block_type_ == 1);
  581.             this->bdescr_.gap_.ptr = BMGAP_PTR(this->block_);
  582.             unsigned bitval = *this->bdescr_.gap_.ptr & 1;
  583.             ++this->bdescr_.gap_.ptr;
  584.             do
  585.             {
  586.                 register unsigned val = *this->bdescr_.gap_.ptr;
  587.                 if (bitval)
  588.                 {
  589.                     gap_word_t* first = BMGAP_PTR(this->block_) + 1;
  590.                     if (this->bdescr_.gap_.ptr == first)
  591.                     {
  592.                         this->bdescr_.gap_.gap_len = val + 1;
  593.                     }
  594.                     else
  595.                     {
  596.                         this->bdescr_.gap_.gap_len
  597.                             = val - *(this->bdescr_.gap_.ptr-1);
  598.                     }
  599.            
  600.                     return true;
  601.                 }
  602.                 this->position_ += val + 1;
  603.                 if (val == bm::gap_max_bits - 1)
  604.                 {
  605.                     break;
  606.                 }
  607.                 bitval ^= 1;
  608.                 ++this->bdescr_.gap_.ptr;
  609.             } while (1);
  610.             return false;
  611.         }
  612.     };
  613.     
  614.     /*!
  615.         @brief Constant input iterator designed to enumerate "ON" bits
  616.         counted_enumerator keeps bitcount, ie number of ON bits starting
  617.         from the position 0 in the bit string up to the currently enumerated bit
  618.         
  619.         When increment operator called current position is increased by 1.
  620.         
  621.         @ingroup bvector
  622.     */
  623.     class counted_enumerator : public enumerator
  624.     {
  625.     public:
  626. #ifndef BM_NO_STL
  627.         typedef std::input_iterator_tag  iterator_category;
  628. #endif
  629.         counted_enumerator() : bit_count_(0){}
  630.         
  631.         counted_enumerator(const enumerator& en)
  632.         : enumerator(en)
  633.         {
  634.             if (this->valid())
  635.                 bit_count_ = 1;
  636.         }
  637.         
  638.         counted_enumerator& operator=(const enumerator& en)
  639.         {
  640.             enumerator* me = this;
  641.             *me = en;
  642.             if (this->valid())
  643.                 bit_count_ = 1;
  644.             return *this;
  645.         }
  646.         
  647.         counted_enumerator& operator++()
  648.         {
  649.             this->go_up();
  650.             if (this->valid())
  651.                 ++bit_count_;
  652.             return *this;
  653.         }
  654.         counted_enumerator operator++(int)
  655.         {
  656.             counted_enumerator tmp(*this);
  657.             this->go_up();
  658.             if (this->valid())
  659.                 ++bit_count_;
  660.             return tmp;
  661.         }
  662.         
  663.         /*! @brief Number of bits ON starting from the .
  664.         
  665.             Method returns number of ON bits fromn the bit 0 to the current bit 
  666.             For the first bit in bitvector it is 1, for the second 2 
  667.         */
  668.         bm::id_t count() const { return bit_count_; }
  669.         
  670.     private:
  671.         bm::id_t   bit_count_;
  672.     };
  673.     friend class iterator_base;
  674.     friend class enumerator;
  675. public:
  676. #ifdef BMCOUNTOPT
  677.     bvector(strategy strat = BM_BIT, 
  678.             const gap_word_t* glevel_len=bm::gap_len_table<true>::_len,
  679.             bm::id_t max_bits = 0) 
  680.     : count_(0),
  681.       count_is_valid_(true),
  682.       blockman_(glevel_len, max_bits),
  683.       new_blocks_strat_(strat)
  684.     {}
  685.     bvector(const bm::bvector<A, MS>& bvect)
  686.      : count_(bvect.count_),
  687.        count_is_valid_(bvect.count_is_valid_),
  688.        blockman_(bvect.blockman_),
  689.        new_blocks_strat_(bvect.new_blocks_strat_)
  690.     {}
  691. #else
  692.     /*!
  693.         brief Constructs bvector class
  694.         param strat - operation mode strategy, 
  695.                        BM_BIT - default strategy, bvector use plain bitset blocks,
  696.                        (performance oriented strategy).
  697.                        BM_GAP - memory effitent strategy, bvector allocates blocks
  698.                        as array of intervals(gaps) and convert blocks into plain bitsets
  699.                        only when enthropy grows.
  700.         param glevel_len - pointer on C-style array keeping GAP block sizes. 
  701.                             (Put bm::gap_len_table_min<true>::_len for GAP memory saving mode)
  702.         param max_bits - maximum number of bits addressable by bvector, 0 means "no limits" (recommended)
  703.         sa bm::gap_len_table bm::gap_len_table_min
  704.     */
  705.     bvector(strategy strat = BM_BIT,
  706.             const gap_word_t* glevel_len=bm::gap_len_table<true>::_len,
  707.             bm::id_t max_bits = 0) 
  708.     : blockman_(glevel_len, max_bits),
  709.       new_blocks_strat_(strat)   
  710.     {}
  711.     bvector(const bvector<A, MS>& bvect)
  712.         :  blockman_(bvect.blockman_),
  713.            new_blocks_strat_(bvect.new_blocks_strat_)
  714.     {}
  715. #endif
  716.     bvector& operator = (const bvector<A, MS>& bvect)
  717.     {
  718.         if (bvect.blockman_.top_block_size() != blockman_.top_block_size())
  719.         {
  720.             blockman_.set_top_block_size(bvect.blockman_.top_block_size());
  721.         }
  722.         else
  723.         {
  724.             clear(false);
  725.         }
  726.         bit_or(bvect);
  727.         return *this;
  728.     }
  729.     reference operator[](bm::id_t n)
  730.     {
  731.         assert(n < bm::id_max);
  732.         return reference(*this, n);
  733.     }
  734.     bool operator[](bm::id_t n) const
  735.     {
  736.         assert(n < bm::id_max);
  737.         return get_bit(n);
  738.     }
  739.     void operator &= (const bvector<A, MS>& bvect)
  740.     {
  741.         bit_and(bvect);
  742.     }
  743.     void operator ^= (const bvector<A, MS>& bvect)
  744.     {
  745.         bit_xor(bvect);
  746.     }
  747.     void operator |= (const bvector<A, MS>& bvect)
  748.     {
  749.         bit_or(bvect);
  750.     }
  751.     void operator -= (const bvector<A, MS>& bvect)
  752.     {
  753.         bit_sub(bvect);
  754.     }
  755.     bool operator < (const bvector<A, MS>& bvect) const
  756.     {
  757.         return compare(bvect) < 0;
  758.     }
  759.     bool operator <= (const bvector<A, MS>& bvect) const
  760.     {
  761.         return compare(bvect) <= 0;
  762.     }
  763.     bool operator > (const bvector<A, MS>& bvect) const
  764.     {
  765.         return compare(bvect) > 0;
  766.     }
  767.     bool operator >= (const bvector<A, MS>& bvect) const
  768.     {
  769.         return compare(bvect) >= 0;
  770.     }
  771.     bool operator == (const bvector<A, MS>& bvect) const
  772.     {
  773.         return compare(bvect) == 0;
  774.     }
  775.     bool operator != (const bvector<A, MS>& bvect) const
  776.     {
  777.         return compare(bvect) != 0;
  778.     }
  779.     bvector<A, MS> operator~() const
  780.     {
  781.         return bvector<A, MS>(*this).invert();
  782.     }
  783.     /*!
  784.         brief Sets bit n if val is true, clears bit n if val is false
  785.         param n - index of the bit to be set
  786.         param val - new bit value
  787.         return *this
  788.     */
  789.     bvector<A, MS>& set(bm::id_t n, bool val = true)
  790.     {
  791.         // calculate logical block number
  792.         unsigned nblock = unsigned(n >>  bm::set_block_shift); 
  793.         int block_type;
  794.         bm::word_t* blk = 
  795.             blockman_.check_allocate_block(nblock, 
  796.                                            val, 
  797.                                            get_new_blocks_strat(), 
  798.                                            &block_type);
  799.         if (!blk) return *this;
  800.         // calculate word number in block and bit
  801.         unsigned nbit   = unsigned(n & bm::set_block_mask); 
  802.         if (block_type == 1) // gap
  803.         {
  804.             unsigned is_set;
  805.             unsigned new_block_len;
  806.             
  807.             new_block_len = 
  808.                 gap_set_value(val, BMGAP_PTR(blk), nbit, &is_set);
  809.             if (is_set)
  810.             {
  811.                 BMCOUNT_ADJ(val)
  812.                 unsigned threshold = 
  813.                 bm::gap_limit(BMGAP_PTR(blk), blockman_.glen());
  814.                 if (new_block_len > threshold) 
  815.                 {
  816.                     extend_gap_block(nblock, BMGAP_PTR(blk));
  817.                 }
  818.             }
  819.         }
  820.         else  // bit block
  821.         {
  822.             unsigned nword  = unsigned(nbit >> bm::set_word_shift); 
  823.             nbit &= bm::set_word_mask;
  824.             bm::word_t* word = blk + nword;
  825.             bm::word_t  mask = (((bm::word_t)1) << nbit);
  826.             if (val)
  827.             {
  828.                 if ( ((*word) & mask) == 0 )
  829.                 {
  830.                     *word |= mask; // set bit
  831.                     BMCOUNT_INC;
  832.                 }
  833.             }
  834.             else
  835.             {
  836.                 if ((*word) & mask)
  837.                 {
  838.                     *word &= ~mask; // clear bit
  839.                     BMCOUNT_DEC;
  840.                 }
  841.             }
  842.         }
  843.         
  844.         return *this;
  845.     }
  846.     /*!
  847.        brief Sets every bit in this bitset to 1.
  848.        return *this
  849.     */
  850.     bvector<A, MS>& set()
  851.     {
  852.         blockman_.set_all_one();
  853.         set(bm::id_max, false);
  854.         BMCOUNT_SET(id_max);
  855.         return *this;
  856.     }
  857.     /*!
  858.         brief Sets all bits in the specified closed interval [left,right]
  859.         
  860.         param left  - interval start
  861.         param right - interval end (closed interval)
  862.         param value - value to set interval in
  863.         
  864.         return *this
  865.     */
  866.     bvector<A, MS>& set_range(bm::id_t left,
  867.                               bm::id_t right,
  868.                               bool     value = true)
  869.     {
  870.         if (right < left)
  871.         {
  872.             return set_range(right, left, value);
  873.         }
  874.         BMCOUNT_VALID(false)
  875.         BM_SET_MMX_GUARD
  876.         // calculate logical number of start and destination blocks
  877.         unsigned nblock_left  = unsigned(left  >>  bm::set_block_shift);
  878.         unsigned nblock_right = unsigned(right >>  bm::set_block_shift);
  879.         bm::word_t* block = blockman_.get_block(nblock_left);
  880.         bool left_gap = BM_IS_GAP(blockman_, block, nblock_left);
  881.         unsigned nbit_left  = unsigned(left  & bm::set_block_mask); 
  882.         unsigned nbit_right = unsigned(right & bm::set_block_mask); 
  883.         unsigned r = 
  884.            (nblock_left == nblock_right) ? nbit_right :(bm::bits_in_block-1);
  885.         // Set bits in the starting block
  886.         bm::gap_word_t tmp_gap_blk[5] = {0,};
  887.         gap_init_range_block(tmp_gap_blk, 
  888.                              nbit_left, r, value, bm::bits_in_block);
  889.         combine_operation_with_block(nblock_left, 
  890.                                      left_gap, 
  891.                                      block,
  892.                                      (bm::word_t*) tmp_gap_blk,
  893.                                      1,
  894.                                      value ? BM_OR : BM_AND);
  895.         if (nblock_left == nblock_right)  // in one block
  896.             return *this;
  897.         // Set (or clear) all blocks between left and right
  898.         
  899.         unsigned nb_to = nblock_right + (nbit_right ==(bm::bits_in_block-1));
  900.                 
  901.         if (value)
  902.         {
  903.             for (unsigned nb = nblock_left+1; nb < nb_to; ++nb)
  904.             {
  905.                 block = blockman_.get_block(nb);
  906.                 if (IS_FULL_BLOCK(block)) 
  907.                     continue;
  908.                 bool is_gap = BM_IS_GAP(blockman_, block, nb);
  909.                 if (is_gap)
  910.                     A::free_gap_block(BMGAP_PTR(block),blockman_.glen());
  911.                 else
  912.                     A::free_bit_block(block);
  913.                 blockman_.set_block(nb, FULL_BLOCK_ADDR);
  914.                 blockman_.set_block_bit(nb);
  915.                 
  916.             } // for
  917.         }
  918.         else // value == 0
  919.         {
  920.             for (unsigned nb = nblock_left+1; nb < nb_to; ++nb)
  921.             {
  922.                 block = blockman_.get_block(nb);
  923.                 if (block == 0)  // nothing to do
  924.                     continue;
  925.                 bool is_gap = BM_IS_GAP(blockman_, block, nb);
  926.                 if (is_gap)
  927.                     A::free_gap_block(BMGAP_PTR(block),blockman_.glen());
  928.                 else
  929.                     A::free_bit_block(block);
  930.                 blockman_.set_block(nb, 0);
  931.                 blockman_.set_block_bit(nb);
  932.             } // for
  933.         } // if value else 
  934.         if (nb_to > nblock_right)
  935.             return *this;
  936.         block = blockman_.get_block(nblock_right);
  937.         bool right_gap = BM_IS_GAP(blockman_, block, nblock_right);
  938.         gap_init_range_block(tmp_gap_blk, 
  939.                              0, nbit_right, value, bm::bits_in_block);
  940.         combine_operation_with_block(nblock_right, 
  941.                                      right_gap, 
  942.                                      block,
  943.                                      (bm::word_t*) tmp_gap_blk,
  944.                                      1,
  945.                                      value ? BM_OR : BM_AND);
  946.         return *this;
  947.     }
  948.     /*!
  949.        brief Sets bit n.
  950.        param n - index of the bit to be set. 
  951.     */
  952.     void set_bit(bm::id_t n)
  953.     {
  954.         set(n, true);
  955.     }
  956.     
  957.     /*! Function erturns insert iterator for this bitvector */
  958.     insert_iterator inserter()
  959.     {
  960.         return insert_iterator(*this);
  961.     }
  962.     /*!
  963.        brief Clears bit n.
  964.        param n - bit's index to be cleaned.
  965.     */
  966.     void clear_bit(bm::id_t n)
  967.     {
  968.         set(n, false);
  969.     }
  970.     /*!
  971.        brief Clears every bit in the bitvector.
  972.        param free_mem if "true" (default) bvector frees the memory,
  973.        otherwise sets blocks to 0.
  974.     */
  975.     void clear(bool free_mem = false)
  976.     {
  977.         blockman_.set_all_zero(free_mem);
  978.         BMCOUNT_SET(0);
  979.     }
  980.     /*!
  981.        brief Clears every bit in the bitvector.
  982.        return *this;
  983.     */
  984.     bvector<A, MS>& reset()
  985.     {
  986.         clear();
  987.         return *this;
  988.     }
  989.     /*!
  990.        brief Returns count of bits which are 1.
  991.        return Total number of bits ON. 
  992.     */
  993.     bm::id_t count() const
  994.     {
  995.     #ifdef BMCOUNTOPT
  996.         if (count_is_valid_) return count_;
  997.     #endif
  998.         bm::word_t*** blk_root = blockman_.get_rootblock();
  999.         typename blocks_manager::block_count_func func(blockman_);
  1000.         for_each_nzblock(blk_root, blockman_.top_block_size(), 
  1001.                                    bm::set_array_size, func);
  1002.         BMCOUNT_SET(func.count());
  1003.         return func.count();
  1004.     }
  1005.     /*! brief Computes bitcount values for all bvector blocks
  1006.         param arr - pointer on array of block bit counts
  1007.         return Index of the last block counted. 
  1008.         This number +1 gives you number of arr elements initialized during the
  1009.         function call.
  1010.     */
  1011.     unsigned count_blocks(unsigned* arr) const
  1012.     {
  1013.         bm::word_t*** blk_root = blockman_.get_rootblock();
  1014.         typename blocks_manager::block_count_arr_func func(blockman_, &(arr[0]));
  1015.         for_each_nzblock(blk_root, blockman_.top_block_size(), 
  1016.                                    bm::set_array_size, func);
  1017.         return func.last_block();
  1018.     }
  1019.     /*!
  1020.        brief Returns count of 1 bits in the given diapason.
  1021.        param left - index of first bit start counting from
  1022.        param right - index of last bit 
  1023.        param block_count_arr - optional parameter (bitcount by bvector blocks)
  1024.               calculated by count_blocks method. Used to improve performance of
  1025.               wide range searches
  1026.        return Total number of bits ON. 
  1027.     */
  1028.     bm::id_t count_range(bm::id_t left, 
  1029.                          bm::id_t right, 
  1030.                          unsigned* block_count_arr=0) const
  1031.     {
  1032.         assert(left <= right);
  1033.         unsigned count = 0;
  1034.         // calculate logical number of start and destination blocks
  1035.         unsigned nblock_left  = unsigned(left  >>  bm::set_block_shift);
  1036.         unsigned nblock_right = unsigned(right >>  bm::set_block_shift);
  1037.         const bm::word_t* block = blockman_.get_block(nblock_left);
  1038.         bool left_gap = BM_IS_GAP(blockman_, block, nblock_left);
  1039.         unsigned nbit_left  = unsigned(left  & bm::set_block_mask); 
  1040.         unsigned nbit_right = unsigned(right & bm::set_block_mask); 
  1041.         unsigned r = 
  1042.            (nblock_left == nblock_right) ? nbit_right : (bm::bits_in_block-1);
  1043.         typename blocks_manager::block_count_func func(blockman_);
  1044.         if (block)
  1045.         {
  1046.             if ((nbit_left == 0) && (r == (bm::bits_in_block-1))) // whole block
  1047.             {
  1048.                 if (block_count_arr)
  1049.                 {
  1050.                     count += block_count_arr[nblock_left];
  1051.                 }
  1052.                 else
  1053.                 {
  1054.                     func(block, nblock_left);
  1055.                 }
  1056.             }
  1057.             else
  1058.             {
  1059.                 if (left_gap)
  1060.                 {
  1061.                     count += gap_bit_count_range(BMGAP_PTR(block), 
  1062.                                                 (gap_word_t)nbit_left,
  1063.                                                 (gap_word_t)r);
  1064.                 }
  1065.                 else
  1066.                 {
  1067.                     count += bit_block_calc_count_range(block, nbit_left, r);
  1068.                 }
  1069.             }
  1070.         }
  1071.         if (nblock_left == nblock_right)  // in one block
  1072.         {
  1073.             return count + func.count();
  1074.         }
  1075.         for (unsigned nb = nblock_left+1; nb < nblock_right; ++nb)
  1076.         {
  1077.             block = blockman_.get_block(nb);
  1078.             if (block_count_arr)
  1079.             {
  1080.                 count += block_count_arr[nb];
  1081.             }
  1082.             else 
  1083.             {
  1084.                 if (block)
  1085.                     func(block, nb);
  1086.             }
  1087.         }
  1088.         count += func.count();
  1089.         block = blockman_.get_block(nblock_right);
  1090.         bool right_gap = BM_IS_GAP(blockman_, block, nblock_right);
  1091.         if (block)
  1092.         {
  1093.             if (right_gap)
  1094.             {
  1095.                 count += gap_bit_count_range(BMGAP_PTR(block),
  1096.                                             (gap_word_t)0,
  1097.                                             (gap_word_t)nbit_right);
  1098.             }
  1099.             else
  1100.             {
  1101.                 count += bit_block_calc_count_range(block, 0, nbit_right);
  1102.             }
  1103.         }
  1104.         return count;
  1105.     }
  1106.     bm::id_t recalc_count()
  1107.     {
  1108.         BMCOUNT_VALID(false)
  1109.         return count();
  1110.     }
  1111.     
  1112.     /*!
  1113.         Disables count cache. Next call to count() or recalc_count()
  1114.         restores count caching.
  1115.         
  1116.         @note Works only if BMCOUNTOPT enabled(defined). 
  1117.         Othewise does nothing.
  1118.     */
  1119.     void forget_count()
  1120.     {
  1121.         BMCOUNT_VALID(false)    
  1122.     }
  1123.     /*!
  1124.         brief Inverts all bits.
  1125.     */
  1126.     bvector<A, MS>& invert()
  1127.     {
  1128.         BMCOUNT_VALID(false)
  1129.         BM_SET_MMX_GUARD
  1130.         bm::word_t*** blk_root = blockman_.get_rootblock();
  1131.         typename blocks_manager::block_invert_func func(blockman_);    
  1132.         for_each_block(blk_root, blockman_.top_block_size(),
  1133.                                  bm::set_array_size, func);
  1134.         set(bm::id_max, false);
  1135.         return *this;
  1136.     }
  1137.     /*!
  1138.        brief returns true if bit n is set and false is bit n is 0. 
  1139.        param n - Index of the bit to check.
  1140.        return Bit value (1 or 0)
  1141.     */
  1142.     bool get_bit(bm::id_t n) const
  1143.     {    
  1144.         BM_ASSERT(n < bm::id_max);
  1145.         // calculate logical block number
  1146.         unsigned nblock = unsigned(n >>  bm::set_block_shift); 
  1147.         const bm::word_t* block = blockman_.get_block(nblock);
  1148.         if (block)
  1149.         {
  1150.             // calculate word number in block and bit
  1151.             unsigned nbit = unsigned(n & bm::set_block_mask); 
  1152.             unsigned is_set;
  1153.             if (BM_IS_GAP(blockman_, block, nblock))
  1154.             {
  1155.                 is_set = gap_test(BMGAP_PTR(block), nbit);
  1156.             }
  1157.             else 
  1158.             {
  1159.                 unsigned nword  = unsigned(nbit >> bm::set_word_shift); 
  1160.                 nbit &= bm::set_word_mask;
  1161.                 is_set = (block[nword] & (((bm::word_t)1) << nbit));
  1162.             }
  1163.             return is_set != 0;
  1164.         }
  1165.         return false;
  1166.     }
  1167.     /*!
  1168.        brief returns true if bit n is set and false is bit n is 0. 
  1169.        param n - Index of the bit to check.
  1170.        return Bit value (1 or 0)
  1171.     */
  1172.     bool test(bm::id_t n) const 
  1173.     { 
  1174.         return get_bit(n); 
  1175.     }
  1176.     /*!
  1177.        brief Returns true if any bits in this bitset are set, and otherwise returns false.
  1178.        return true if any bit is set
  1179.     */
  1180.     bool any() const
  1181.     {
  1182.     #ifdef BMCOUNTOPT
  1183.         if (count_is_valid_ && count_) return true;
  1184.     #endif
  1185.         
  1186.         bm::word_t*** blk_root = blockman_.get_rootblock();
  1187.         typename blocks_manager::block_any_func func(blockman_);
  1188.         return for_each_nzblock_if(blk_root, blockman_.top_block_size(),
  1189.                                              bm::set_array_size, func);
  1190.     }
  1191.     /*!
  1192.         brief Returns true if no bits are set, otherwise returns false.
  1193.     */
  1194.     bool none() const
  1195.     {
  1196.         return !any();
  1197.     }
  1198.     /*!
  1199.        brief Flips bit n
  1200.        return *this
  1201.     */
  1202.     bvector<A, MS>& flip(bm::id_t n) 
  1203.     {
  1204.         set(n, !get_bit(n));
  1205.         return *this;
  1206.     }
  1207.     /*!
  1208.        brief Flips all bits
  1209.        return *this
  1210.     */
  1211.     bvector<A, MS>& flip() 
  1212.     {
  1213.         return invert();
  1214.     }
  1215.     /*! brief Exchanges content of bv and this bitvector.
  1216.     */
  1217.     void swap(bvector<A, MS>& bv)
  1218.     {
  1219.         blockman_.swap(bv.blockman_);
  1220. #ifdef BMCOUNTOPT
  1221.         BMCOUNT_VALID(false)
  1222.         bv.recalc_count();
  1223. #endif
  1224.     }
  1225.     /*!
  1226.        fn bm::id_t bvector::get_first() const
  1227.        brief Gets number of first bit which is ON.
  1228.        return Index of the first 1 bit.
  1229.        sa get_next
  1230.     */
  1231.     bm::id_t get_first() const { return check_or_next(0); }
  1232.     /*!
  1233.        fn bm::id_t bvector::get_next(bm::id_t prev) const
  1234.        brief Finds the number of the next bit ON.
  1235.        param prev - Index of the previously found bit. 
  1236.        return Index of the next bit which is ON or 0 if not found.
  1237.        sa get_first
  1238.     */
  1239.     bm::id_t get_next(bm::id_t prev) const
  1240.     {
  1241.         return (++prev == bm::id_max) ? 0 : check_or_next(prev);
  1242.     }
  1243.     /*!
  1244.        @brief Calculates bitvector statistics.
  1245.        @param st - pointer on statistics structure to be filled in. 
  1246.        Function fills statistics structure containing information about how 
  1247.        this vector uses memory and estimation of max. amount of memory 
  1248.        bvector needs to serialize itself.
  1249.        @sa statistics
  1250.     */
  1251.     void calc_stat(struct statistics* st) const;
  1252.     /*!
  1253.        brief Logical OR operation.
  1254.        param vect - Argument vector.
  1255.     */
  1256.     bm::bvector<A, MS>& bit_or(const  bm::bvector<A, MS>& vect)
  1257.     {
  1258.         BMCOUNT_VALID(false);
  1259.         combine_operation(vect, BM_OR);
  1260.         return *this;
  1261.     }
  1262.     /*!
  1263.        brief Logical AND operation.
  1264.        param vect - Argument vector.
  1265.     */
  1266.     bm::bvector<A, MS>& bit_and(const bm::bvector<A, MS>& vect)
  1267.     {
  1268.         BMCOUNT_VALID(false);
  1269.         combine_operation(vect, BM_AND);
  1270.         return *this;
  1271.     }
  1272.     /*!
  1273.        brief Logical XOR operation.
  1274.        param vect - Argument vector.
  1275.     */
  1276.     bm::bvector<A, MS>& bit_xor(const bm::bvector<A, MS>& vect)
  1277.     {
  1278.         BMCOUNT_VALID(false);
  1279.         combine_operation(vect, BM_XOR);
  1280.         return *this;
  1281.     }
  1282.     /*!
  1283.        brief Logical SUB operation.
  1284.        param vect - Argument vector.
  1285.     */
  1286.     bm::bvector<A, MS>& bit_sub(const bm::bvector<A, MS>& vect)
  1287.     {
  1288.         BMCOUNT_VALID(false);
  1289.         combine_operation(vect, BM_SUB);
  1290.         return *this;
  1291.     }
  1292.     /*!
  1293.        brief Sets new blocks allocation strategy.
  1294.        param strat - Strategy code 0 - bitblocks allocation only.
  1295.                       1 - Blocks mutation mode (adaptive algorithm)
  1296.     */
  1297.     void set_new_blocks_strat(strategy strat) 
  1298.     { 
  1299.         new_blocks_strat_ = strat; 
  1300.     }
  1301.     /*!
  1302.        brief Returns blocks allocation strategy.
  1303.        return - Strategy code 0 - bitblocks allocation only.
  1304.                  1 - Blocks mutation mode (adaptive algorithm)
  1305.        sa set_new_blocks_strat
  1306.     */
  1307.     strategy  get_new_blocks_strat() const 
  1308.     { 
  1309.         return new_blocks_strat_; 
  1310.     }
  1311.     void stat(unsigned blocks=0) const;
  1312.     /*!
  1313.        brief Optimize memory bitvector's memory allocation.
  1314.    
  1315.        Function analyze all blocks in the bitvector, compresses blocks 
  1316.        with a regular structure, frees some memory. This function is recommended
  1317.        after a bulk modification of the bitvector using set_bit, clear_bit or
  1318.        logical operations.
  1319.     */
  1320.     void optimize(bm::word_t* temp_block=0)
  1321.     {
  1322.         bm::word_t*** blk_root = blockman_.blocks_root();
  1323.         if (!temp_block)
  1324.             temp_block = blockman_.check_allocate_tempblock();
  1325.         typename 
  1326.           blocks_manager::block_opt_func  opt_func(blockman_, temp_block);
  1327.         for_each_nzblock(blk_root, blockman_.top_block_size(),
  1328.                                    bm::set_array_size, opt_func);
  1329.     }
  1330.     
  1331.     void optimize_gap_size()
  1332.     {
  1333.         struct bvector<A, MS>::statistics st;
  1334.         calc_stat(&st);
  1335.         if (!st.gap_blocks)
  1336.             return;
  1337.         gap_word_t opt_glen[bm::gap_levels];
  1338.         ::memcpy(opt_glen, st.gap_levels, bm::gap_levels * sizeof(*opt_glen));
  1339.         improve_gap_levels(st.gap_length, 
  1340.                                 st.gap_length + st.gap_blocks, 
  1341.                                 opt_glen);
  1342.         
  1343.         set_gap_levels(opt_glen);
  1344.     }
  1345.     /*!
  1346.         @brief Sets new GAP lengths table. All GAP blocks will be reallocated 
  1347.         to match the new scheme.
  1348.         @param glevel_len - pointer on C-style array keeping GAP block sizes. 
  1349.     */
  1350.     void set_gap_levels(const gap_word_t* glevel_len)
  1351.     {
  1352.         bm::word_t*** blk_root = blockman_.blocks_root();
  1353.         typename 
  1354.             blocks_manager::gap_level_func  gl_func(blockman_, glevel_len);
  1355.         for_each_nzblock(blk_root, blockman_.top_block_size(),
  1356.                                    bm::set_array_size, gl_func);
  1357.         blockman_.set_glen(glevel_len);
  1358.     }
  1359.     /*!
  1360.         brief Lexicographical comparison with a bitvector.
  1361.         Function compares current bitvector with the provided argument 
  1362.         bit by bit and returns -1 if our bitvector less than the argument, 
  1363.         1 - greater, 0 - equal.
  1364.     */
  1365.     int compare(const bvector<A, MS>& bvect) const
  1366.     {
  1367.         int res;
  1368.         unsigned bn = 0;
  1369.         for (unsigned i = 0; i < blockman_.top_block_size(); ++i)
  1370.         {
  1371.             const bm::word_t* const* blk_blk = blockman_.get_topblock(i);
  1372.             const bm::word_t* const* arg_blk_blk = 
  1373.                                    bvect.blockman_.get_topblock(i);
  1374.             if (blk_blk == arg_blk_blk) 
  1375.             {
  1376.                 bn += bm::set_array_size;
  1377.                 continue;
  1378.             }
  1379.             for (unsigned j = 0; j < bm::set_array_size; ++j, ++bn)
  1380.             {
  1381.                 const bm::word_t* arg_blk = 
  1382.                                     arg_blk_blk ? arg_blk_blk[j] : 0;
  1383.                 const bm::word_t* blk = blk_blk ? blk_blk[j] : 0;
  1384.                 if (blk == arg_blk) continue;
  1385.                 // If one block is zero we check if the other one has at least 
  1386.                 // one bit ON
  1387.                 if (!blk || !arg_blk)  
  1388.                 {
  1389.                     const bm::word_t*  pblk;
  1390.                     bool is_gap;
  1391.                     if (blk)
  1392.                     {
  1393.                         pblk = blk;
  1394.                         res = 1;
  1395.                         is_gap = BM_IS_GAP((*this), blk, bn);
  1396.                     }
  1397.                     else
  1398.                     {
  1399.                         pblk = arg_blk;
  1400.                         res = -1;
  1401.                         is_gap = BM_IS_GAP(bvect, arg_blk, bn);
  1402.                     }
  1403.                     if (is_gap)
  1404.                     {
  1405.                         if (!gap_is_all_zero(BMGAP_PTR(pblk), bm::gap_max_bits))
  1406.                         {
  1407.                             return res;
  1408.                         }
  1409.                     }
  1410.                     else
  1411.                     {
  1412.                         bm::wordop_t* blk1 = (wordop_t*)pblk;
  1413.                         bm::wordop_t* blk2 = 
  1414.                             (wordop_t*)(pblk + bm::set_block_size);
  1415.                         if (!bit_is_all_zero(blk1, blk2))
  1416.                         {
  1417.                             return res;
  1418.                         }
  1419.                     }
  1420.                     continue;
  1421.                 }
  1422.                 bool arg_gap = BM_IS_GAP(bvect, arg_blk, bn);
  1423.                 bool gap = BM_IS_GAP((*this), blk, bn);
  1424.                 if (arg_gap != gap)
  1425.                 {
  1426.                     bm::wordop_t temp_blk[bm::set_block_size_op]; 
  1427.                     bm::wordop_t* blk1;
  1428.                     bm::wordop_t* blk2;
  1429.                     if (gap)
  1430.                     {
  1431.                         gap_convert_to_bitset((bm::word_t*)temp_blk, 
  1432.                                               BMGAP_PTR(blk), 
  1433.                                               bm::set_block_size);
  1434.                         blk1 = (bm::wordop_t*)temp_blk;
  1435.                         blk2 = (bm::wordop_t*)arg_blk;
  1436.                     }
  1437.                     else
  1438.                     {
  1439.                         gap_convert_to_bitset((bm::word_t*)temp_blk, 
  1440.                                               BMGAP_PTR(arg_blk), 
  1441.                                               bm::set_block_size);
  1442.                         blk1 = (bm::wordop_t*)blk;
  1443.                         blk2 = (bm::wordop_t*)temp_blk;
  1444.                     }                        
  1445.                     res = bitcmp(blk1, blk2, bm::set_block_size_op);  
  1446.                 }
  1447.                 else
  1448.                 {
  1449.                     if (gap)
  1450.                     {
  1451.                         res = gapcmp(BMGAP_PTR(blk), BMGAP_PTR(arg_blk));
  1452.                     }
  1453.                     else
  1454.                     {
  1455.                         res = bitcmp((bm::wordop_t*)blk, 
  1456.                                      (bm::wordop_t*)arg_blk, 
  1457.                                       bm::set_block_size_op);
  1458.                     }
  1459.                 }
  1460.                 if (res != 0)
  1461.                 {
  1462.                     return res;
  1463.                 }
  1464.             
  1465.             } // for j
  1466.         } // for i
  1467.         return 0;
  1468.     }
  1469.     /*! @brief Allocates temporary block of memory. 
  1470.         Temp block can be passed to bvector functions requiring some temp memory
  1471.         for their operation. (like serialize)
  1472.         @sa free_tempblock
  1473.     */
  1474.     static bm::word_t* allocate_tempblock()
  1475.     {
  1476.         return A::alloc_bit_block();
  1477.     }
  1478.     /*! @brief Frees temporary block of memory. 
  1479.         @sa allocate_tempblock
  1480.     */
  1481.     static void free_tempblock(bm::word_t* block)
  1482.     {
  1483.         A::free_bit_block(block);
  1484.     }
  1485.     /*!
  1486.        @brief Serilizes bitvector into memory.
  1487.        Allocates temporary memory block for bvector.
  1488.        @sa serialize_const
  1489.     */
  1490.     unsigned serialize(unsigned char* buf)
  1491.     {
  1492.         return serialize(buf, blockman_.check_allocate_tempblock());
  1493.     }
  1494.     /*!
  1495.        brief Serilizes bitvector into memory.
  1496.   
  1497.        Function serializes content of the bitvector into memory.
  1498.        Serialization adaptively uses compression(variation of GAP encoding) 
  1499.        when it is benefitial. 
  1500.    
  1501.        param buf - pointer on target memory area. No range checking in the
  1502.        function. It is responsibility of programmer to allocate sufficient 
  1503.        amount of memory using information from calc_stat function.
  1504.        param temp_block - pointer on temporary memory block. Cannot be 0; 
  1505.        If you want to save memory across multiple bvectors
  1506.        allocate temporary block using allocate_tempblock and pass it to 
  1507.        serialize_const.
  1508.        (Of course serialize does not deallocate temp_block.)
  1509.        return Size of serialization block.
  1510.        sa calc_stat
  1511.     */
  1512.     /*
  1513.      Serialization format:
  1514.      <pre>
  1515.   
  1516.      | HEADER | BLOCKS |
  1517.      Header structure:
  1518.        BYTE : Serialization type (0x1)
  1519.        BYTE : Byte order ( 0 - Big Endian, 1 - Little Endian)
  1520.        INT16: Reserved (0)
  1521.        INT16: Reserved Flags (0)
  1522.   
  1523.      </pre>
  1524.     */
  1525.     unsigned serialize(unsigned char* buf, bm::word_t* temp_block) const
  1526.     {
  1527.         bm::encoder enc(buf, 0);
  1528.         assert(temp_block);
  1529.         gap_word_t*  gap_temp_block = (gap_word_t*) temp_block;
  1530.         // Header
  1531.         ByteOrder bo = globals<true>::byte_order();
  1532.             // g_initial_setup.get_byte_order();
  1533.         enc.put_8(1);
  1534.         enc.put_8((unsigned char)bo);
  1535.         unsigned i,j;
  1536.         // keep GAP levels information
  1537.         for (i = 0; i < bm::gap_levels; ++i)
  1538.         {
  1539.             enc.put_16(blockman_.glen()[i]);
  1540.         }
  1541.         // Blocks.
  1542.         for (i = 0; i < bm::set_total_blocks; ++i)
  1543.         {
  1544.             bm::word_t* blk = blockman_.get_block(i);
  1545.             // -----------------------------------------
  1546.             // Empty or ONE block serialization
  1547.             bool flag;
  1548.             flag = blockman_.is_block_zero(i, blk);
  1549.             if (flag)
  1550.             {
  1551.                 // Look ahead for similar blocks
  1552.                 for(j = i+1; j < bm::set_total_blocks; ++j)
  1553.                 {
  1554.                    bm::word_t* blk_next = blockman_.get_block(j);
  1555.                    if (flag != blockman_.is_block_zero(j, blk_next))
  1556.                        break;
  1557.                 }
  1558.                 if (j == bm::set_total_blocks)
  1559.                 {
  1560.                     enc.put_8(set_block_azero);
  1561.                     break; 
  1562.                 }
  1563.                 else
  1564.                 {
  1565.                    unsigned nb = j - i;
  1566.                    SER_NEXT_GRP(enc, nb, set_block_1zero, 
  1567.                                          set_block_8zero, 
  1568.                                          set_block_16zero, 
  1569.                                          set_block_32zero) 
  1570.                 }
  1571.                 i = j - 1;
  1572.                 continue;
  1573.             }
  1574.             else
  1575.             {
  1576.                 flag = blockman_.is_block_one(i, blk);
  1577.                 if (flag)
  1578.                 {
  1579.                     // Look ahead for similar blocks
  1580.                     for(j = i+1; j < bm::set_total_blocks; ++j)
  1581.                     {
  1582.                        bm::word_t* blk_next = blockman_.get_block(j);
  1583.                        if (flag != blockman_.is_block_one(j, blk_next))
  1584.                            break;
  1585.                     }
  1586.                     if (j == bm::set_total_blocks)
  1587.                     {
  1588.                         enc.put_8(set_block_aone);
  1589.                         break;
  1590.                     }
  1591.                     else
  1592.                     {
  1593.                        unsigned nb = j - i;
  1594.                        SER_NEXT_GRP(enc, nb, set_block_1one, 
  1595.                                              set_block_8one, 
  1596.                                              set_block_16one, 
  1597.                                              set_block_32one) 
  1598.                     }
  1599.                     i = j - 1;
  1600.                     continue;
  1601.                 }
  1602.             }
  1603.             // ------------------------------
  1604.             // GAP serialization
  1605.             if (BM_IS_GAP(blockman_, blk, i))
  1606.             {
  1607.                 gap_word_t* gblk = BMGAP_PTR(blk);
  1608.                 unsigned len = gap_length(gblk);
  1609.                 enc.put_8(set_block_gap);
  1610.                 for (unsigned k = 0; k < (len-1); ++k)
  1611.                 {
  1612.                     enc.put_16(gblk[k]);
  1613.                 }
  1614.                 continue;
  1615.             }
  1616.             // -------------------------------
  1617.             // BIT BLOCK serialization
  1618.        
  1619.             // Try to reduce the size up to the reasonable limit.
  1620.     /*
  1621.             unsigned len = bm::bit_convert_to_gap(gap_temp_block, 
  1622.                                                   blk, 
  1623.                                                   bm::GAP_MAX_BITS, 
  1624.                                                   bm::GAP_EQUIV_LEN-64);
  1625.     */
  1626.             gap_word_t len;
  1627.             len = bit_convert_to_arr(gap_temp_block, 
  1628.                                      blk, 
  1629.                                      bm::gap_max_bits, 
  1630.                                      bm::gap_equiv_len-64);
  1631.             if (len)  // reduced
  1632.             {
  1633.     //            len = gap_length(gap_temp_block);
  1634.     //            enc.put_8(SET_BLOCK_GAPBIT);
  1635.     //            enc.memcpy(gap_temp_block, sizeof(gap_word_t) * (len - 1));
  1636.                 enc.put_8(set_block_arrbit);
  1637.                 if (sizeof(gap_word_t) == 2)
  1638.                 {
  1639.                     enc.put_16(len);
  1640.                 }
  1641.                 else
  1642.                 {
  1643.                     enc.put_32(len);
  1644.                 }
  1645.                 for (unsigned k = 0; k < len; ++k)
  1646.                 {
  1647.                     enc.put_16(gap_temp_block[k]);
  1648.                 } 
  1649.                 // enc.memcpy(gap_temp_block, sizeof(gap_word_t) * len);
  1650.             }
  1651.             else
  1652.             {
  1653.                 enc.put_8(set_block_bit);
  1654.                 enc.memcpy(blk, sizeof(bm::word_t) * bm::set_block_size);
  1655.             }
  1656.         }
  1657.         enc.put_8(set_block_end);
  1658.         return enc.size();
  1659.     }
  1660.     /*!
  1661.         @brief Bitvector deserialization from memory.
  1662.         @param buf - pointer on memory which keeps serialized bvector
  1663.         @param temp_block - pointer on temporary block, 
  1664.                 if NULL bvector allocates own.
  1665.         @return Number of bytes consumed by deserializer.
  1666.         Function desrializes bitvector from memory block containig results
  1667.         of previous serialization. Function does not remove bits 
  1668.         which are currently set. Effectively it means OR logical operation 
  1669.         between current bitset and previously serialized one.
  1670.     */
  1671.     unsigned deserialize(const unsigned char* buf, bm::word_t* temp_block=0)
  1672.     {
  1673.         bm::wordop_t* tmp_buf = 
  1674.             temp_block ? (bm::wordop_t*) temp_block 
  1675.                        : (bm::wordop_t*)blockman_.check_allocate_tempblock();
  1676.         temp_block = (word_t*)tmp_buf;
  1677.         gap_word_t   gap_temp_block[set_block_size*2+10];
  1678.         ByteOrder bo_current = globals<true>::byte_order();
  1679.         bm::decoder dec(buf);
  1680.         BMCOUNT_VALID(false);
  1681.         BM_SET_MMX_GUARD
  1682.         // Reading header
  1683.         // unsigned char stype =  
  1684.         dec.get_8();
  1685.         ByteOrder bo = (bm::ByteOrder)dec.get_8();
  1686.         assert(bo == bo_current); // TO DO: Add Byte-Order convertions here
  1687.         unsigned i;
  1688.         gap_word_t glevels[bm::gap_levels];
  1689.         // keep GAP levels information
  1690.         for (i = 0; i < bm::gap_levels; ++i)
  1691.         {
  1692.             glevels[i] = dec.get_16();
  1693.         }
  1694.         // Reading blocks
  1695.         unsigned char btype;
  1696.         unsigned nb;
  1697.         for (i = 0; i < bm::set_total_blocks; ++i)
  1698.         {
  1699.             // get the block type
  1700.         
  1701.             btype = dec.get_8();
  1702.  
  1703.             // In a few next blocks of code we simply ignoring all coming zero blocks.
  1704.             if (btype == set_block_azero || btype == set_block_end)
  1705.             {
  1706.                 break;
  1707.             }
  1708.             if (btype == set_block_1zero)
  1709.             {
  1710.                 continue;
  1711.             }
  1712.             if (btype == set_block_8zero)
  1713.             {
  1714.                 nb = dec.get_8();
  1715.                 i += nb-1;
  1716.                 continue;
  1717.             }
  1718.             if (btype == set_block_16zero)
  1719.             {
  1720.                 nb = dec.get_16();
  1721.                 i += nb-1;
  1722.                 continue;
  1723.             }
  1724.             if (btype == set_block_32zero)
  1725.             {
  1726.                 nb = dec.get_32();
  1727.                 i += nb-1;
  1728.                 continue;
  1729.             }
  1730.             // Now it is turn of all-set blocks (111)
  1731.             if (btype == set_block_aone)
  1732.             {
  1733.                 for (unsigned j = i; j < bm::set_total_blocks; ++j)
  1734.                 {
  1735.                     blockman_.set_block_all_set(j);
  1736.                 }
  1737.                 break;
  1738.             }
  1739.             if (btype == set_block_1one)
  1740.             {
  1741.                 blockman_.set_block_all_set(i);
  1742.                 continue;
  1743.             }
  1744.             if (btype == set_block_8one)
  1745.             {
  1746.                 BM_SET_ONE_BLOCKS(dec.get_8());
  1747.                 continue;
  1748.             }
  1749.             if (btype == set_block_16one)
  1750.             {
  1751.                 BM_SET_ONE_BLOCKS(dec.get_16());
  1752.                 continue;
  1753.             }
  1754.             if (btype == set_block_32one)
  1755.             {
  1756.                 BM_SET_ONE_BLOCKS(dec.get_32());
  1757.                 continue;
  1758.             }
  1759.             bm::word_t* blk = blockman_.get_block(i);
  1760.             if (btype == set_block_bit) 
  1761.             {
  1762.                 if (blk == 0)
  1763.                 {
  1764.                     blk = A::alloc_bit_block();
  1765.                     blockman_.set_block(i, blk);
  1766.                     dec.memcpy(blk, sizeof(bm::word_t) * bm::set_block_size);
  1767.                     continue;                
  1768.                 }
  1769.                 dec.memcpy(temp_block, sizeof(bm::word_t) * bm::set_block_size);
  1770.                 combine_operation_with_block(i, 
  1771.                                              temp_block, 
  1772.                                              0, BM_OR);
  1773.                 continue;
  1774.             }
  1775.             if (btype == set_block_gap || btype == set_block_gapbit)
  1776.             {
  1777.                 gap_word_t gap_head = 
  1778.                     sizeof(gap_word_t) == 2 ? dec.get_16() : dec.get_32();
  1779.                 unsigned len = gap_length(&gap_head);
  1780.                 int level = gap_calc_level(len, blockman_.glen());
  1781.                 --len;
  1782.                 if (level == -1)  // Too big to be GAP: convert to BIT block
  1783.                 {
  1784.                     *gap_temp_block = gap_head;
  1785.                     dec.memcpy(gap_temp_block+1, (len-1) * sizeof(gap_word_t));
  1786.                     gap_temp_block[len] = gap_max_bits - 1;
  1787.                     if (blk == 0)  // block does not exist yet
  1788.                     {
  1789.                         blk = A::alloc_bit_block();
  1790.                         blockman_.set_block(i, blk);
  1791.                         gap_convert_to_bitset(blk, 
  1792.                                               gap_temp_block, 
  1793.                                               bm::set_block_size);                
  1794.                     }
  1795.                     else  // We have some data already here. Apply OR operation.
  1796.                     {
  1797.                         gap_convert_to_bitset(temp_block, 
  1798.                                               gap_temp_block, 
  1799.                                               bm::set_block_size);
  1800.                         combine_operation_with_block(i, 
  1801.                                                     temp_block, 
  1802.                                                     0, 
  1803.                                                     BM_OR);
  1804.                     }
  1805.                     continue;
  1806.                 } // level == -1
  1807.                 set_gap_level(&gap_head, level);
  1808.             
  1809.                 if (blk == 0)
  1810.                 {
  1811.                     gap_word_t* gap_blk = A::alloc_gap_block(level, blockman_.glen());
  1812.                     gap_word_t* gap_blk_ptr = BMGAP_PTR(gap_blk);
  1813.                     *gap_blk_ptr = gap_head;
  1814.                     set_gap_level(gap_blk_ptr, level);
  1815.                     blockman_.set_block(i, (bm::word_t*)gap_blk);
  1816.                     blockman_.set_block_gap(i);
  1817.                     for (unsigned k = 1; k < len; ++k) 
  1818.                     {
  1819.                          gap_blk[k] = dec.get_16();
  1820.                     }
  1821.                     gap_blk[len] = bm::gap_max_bits - 1;
  1822.                 }
  1823.                 else
  1824.                 {
  1825.                     *gap_temp_block = gap_head;
  1826.                     for (unsigned k = 1; k < len; ++k) 
  1827.                     {
  1828.                          gap_temp_block[k] = dec.get_16();
  1829.                     }
  1830.                     gap_temp_block[len] = bm::gap_max_bits - 1;
  1831.                     combine_operation_with_block(i, 
  1832.                                                 (bm::word_t*)gap_temp_block, 
  1833.                                                  1, 
  1834.                                                  BM_OR);
  1835.                 }
  1836.                 continue;
  1837.             }
  1838.             if (btype == set_block_arrbit)
  1839.             {
  1840.                 gap_word_t len = 
  1841.                     sizeof(gap_word_t) == 2 ? dec.get_16() : dec.get_32();
  1842.                 // check the block type.
  1843.                 if (blockman_.is_block_gap(i))
  1844.                 {
  1845.                     // Here we most probably does not want to keep
  1846.                     // the block GAP since generic bitblock offers better
  1847.                     // performance.
  1848.                     blk = blockman_.convert_gap2bitset(i);
  1849.                 }
  1850.                 else
  1851.                 {
  1852.                     if (blk == 0)  // block does not exists yet
  1853.                     {
  1854.                         blk = A::alloc_bit_block();
  1855.                         bit_block_set(blk, 0);
  1856.                         blockman_.set_block(i, blk);
  1857.                     }
  1858.                 }
  1859.                 // Get the array one by one and set the bits.
  1860.                 for (unsigned k = 0; k < len; ++k)
  1861.                 {
  1862.                     gap_word_t bit_idx = dec.get_16();
  1863.                     or_bit_block(blk, bit_idx, 1);
  1864.                 }
  1865.                 continue;
  1866.             }
  1867. /*
  1868.             if (btype == set_block_gapbit)
  1869.             {
  1870.                 gap_word_t gap_head = 
  1871.                     sizeof(gap_word_t) == 2 ? dec.get_16() : dec.get_32();
  1872.                 unsigned len = gap_length(&gap_head)-1;
  1873.                 *gap_temp_block = gap_head;
  1874.                 dec.memcpy(gap_temp_block+1, (len-1) * sizeof(gap_word_t));
  1875.                 gap_temp_block[len] = GAP_MAX_BITS - 1;
  1876.                 if (blk == 0)  // block does not exists yet
  1877.                 {
  1878.                     blk = A::alloc_bit_block();
  1879.                     blockman_.set_block(i, blk);
  1880.                     gap_convert_to_bitset(blk, 
  1881.                                           gap_temp_block, 
  1882.                                           bm::SET_BLOCK_SIZE);                
  1883.                 }
  1884.                 else  // We have some data already here. Apply OR operation.
  1885.                 {
  1886.                     gap_convert_to_bitset(temp_block, 
  1887.                                           gap_temp_block, 
  1888.                                           bm::SET_BLOCK_SIZE);
  1889.                     combine_operation_with_block(i, 
  1890.                                                  temp_block, 
  1891.                                                  0, 
  1892.                                                  BM_OR);
  1893.                 }
  1894.                 continue;
  1895.             }
  1896. */
  1897.             assert(0); // unknown block type
  1898.         
  1899.         } // for i
  1900.         return dec.size();
  1901.     }
  1902.     /**
  1903.        brief Returns enumerator pointing on the first non-zero bit.
  1904.     */
  1905.     enumerator first() const
  1906.     {
  1907.         typedef typename bvector<A, MS>::enumerator TEnumerator;
  1908.         return TEnumerator(this, 0);
  1909.     }
  1910.     /**
  1911.        fn bvector::enumerator bvector::end() const
  1912.        brief Returns enumerator pointing on the next bit after the last.
  1913.     */
  1914.     enumerator end() const
  1915.     {
  1916.         typedef typename bvector<A, MS>::enumerator TEnumerator;
  1917.         return TEnumerator(this, 1);
  1918.     }
  1919.     const bm::word_t* get_block(unsigned nb) const 
  1920.     { 
  1921.         return blockman_.get_block(nb); 
  1922.     }
  1923.     
  1924. private:
  1925.     bm::id_t check_or_next(bm::id_t prev) const
  1926.     {
  1927.         for (;;)
  1928.         {
  1929.             unsigned nblock = unsigned(prev >> bm::set_block_shift); 
  1930.             if (nblock >= bm::set_total_blocks) break;
  1931.             if (blockman_.is_subblock_null(nblock >> bm::set_array_shift))
  1932.             {
  1933.                 prev += (bm::set_blkblk_mask + 1) -
  1934.                               (prev & bm::set_blkblk_mask);
  1935.             }
  1936.             else
  1937.             {
  1938.                 unsigned nbit = unsigned(prev & bm::set_block_mask);
  1939.                 const bm::word_t* block = blockman_.get_block(nblock);
  1940.     
  1941.                 if (block)
  1942.                 {
  1943.                     if (IS_FULL_BLOCK(block)) return prev;
  1944.                     if (BM_IS_GAP(blockman_, block, nblock))
  1945.                     {
  1946.                         if (gap_find_in_block(BMGAP_PTR(block), nbit, &prev))
  1947.                         {
  1948.                             return prev;
  1949.                         }
  1950.                     }
  1951.                     else
  1952.                     {
  1953.                         if (bit_find_in_block(block, nbit, &prev)) 
  1954.                         {
  1955.                             return prev;
  1956.                         }
  1957.                     }
  1958.                 }
  1959.                 else
  1960.                 {
  1961.                     prev += (bm::set_block_mask + 1) - 
  1962.                                 (prev & bm::set_block_mask);
  1963.                 }
  1964.             }
  1965.             if (!prev) break;
  1966.         }
  1967.         return 0;
  1968.     }
  1969.     
  1970.     void combine_operation(const bm::bvector<A, MS>& bvect, 
  1971.                            bm::operation opcode)
  1972.     {
  1973.         typedef void (*block_bit_op)(bm::word_t*, const bm::word_t*);
  1974.         typedef void (*block_bit_op_next)(bm::word_t*, 
  1975.                                           const bm::word_t*, 
  1976.                                           bm::word_t*, 
  1977.                                           const bm::word_t*);
  1978.         
  1979.         block_bit_op      bit_func;
  1980.         switch (opcode)
  1981.         {
  1982.         case BM_AND:
  1983.             bit_func = bit_block_and;
  1984.             break;
  1985.         case BM_OR:
  1986.             bit_func = bit_block_or;
  1987.             break;
  1988.         case BM_SUB:
  1989.             bit_func = bit_block_sub;
  1990.             break;
  1991.         case BM_XOR:
  1992.             bit_func = bit_block_xor;
  1993.             break;
  1994.         }           
  1995.        
  1996.         
  1997.         bm::word_t*** blk_root = blockman_.blocks_root();
  1998.         unsigned block_idx = 0;
  1999.         unsigned i, j;
  2000.         BM_SET_MMX_GUARD
  2001.         for (i = 0; i < blockman_.top_block_size(); ++i)
  2002.         {
  2003.             bm::word_t** blk_blk = blk_root[i];
  2004.             if (blk_blk == 0) // not allocated
  2005.             {
  2006.                 const bm::word_t* const* bvbb = 
  2007.                                 bvect.blockman_.get_topblock(i);
  2008.                 if (bvbb == 0) 
  2009.                 {
  2010.                     block_idx += bm::set_array_size;
  2011.                     continue;
  2012.                 }
  2013.                 for (j = 0; j < bm::set_array_size; ++j,++block_idx)
  2014.                 {
  2015.                     const bm::word_t* arg_blk = bvect.blockman_.get_block(i, j);
  2016.                     if (arg_blk != 0)
  2017.                     {
  2018.                        bool arg_gap = BM_IS_GAP(bvect.blockman_, arg_blk, block_idx);
  2019.                        
  2020.                        combine_operation_with_block(block_idx, 0, 0, 
  2021.                                                     arg_blk, arg_gap, 
  2022.                                                     opcode);
  2023.                     }
  2024.                 } // for k
  2025.                 continue;
  2026.             }
  2027.             for (j = 0; j < bm::set_array_size; ++j, ++block_idx)
  2028.             {
  2029.                 
  2030.                 bm::word_t* blk = blk_blk[j];
  2031.                 const bm::word_t* arg_blk = bvect.blockman_.get_block(i, j);
  2032.                 if (arg_blk || blk)
  2033.                 {
  2034.                    bool arg_gap = BM_IS_GAP(bvect.blockman_, arg_blk, block_idx);
  2035.                    bool gap = BM_IS_GAP((*this).blockman_, blk, block_idx);
  2036.                    
  2037.                    // Optimization branch. Statistically two bit blocks
  2038.                    // are bumping into each other quite frequently and
  2039.                    // this peace of code tend to be executed often and 
  2040.                    // program does not go into nested calls.
  2041.                    // But logically this branch can be eliminated without
  2042.                    // loosing any functionality.
  2043. /*                   
  2044.                    if (!gap && !arg_gap)
  2045.                    {
  2046.                        if (IS_VALID_ADDR(blk) && arg_blk)
  2047.                        {
  2048.                        
  2049.                             if (bit_func2 && (j < bm::set_array_size-1))
  2050.                             {
  2051.                                 bm::word_t* blk2 = blk_blk[j+1];
  2052.                                 const bm::word_t* arg_blk2 = bvect.get_block(i, j+1);
  2053.                                 
  2054.                                 bool arg_gap2 = BM_IS_GAP(bvect, arg_blk2, block_idx + 1);
  2055.                                 bool gap2 = BM_IS_GAP((*this), blk2, block_idx + 1);
  2056.                                
  2057.                                if (!gap2 && !arg_gap2 && blk2 && arg_blk2)
  2058.                                {
  2059.                                     bit_func2(blk, arg_blk, blk2, arg_blk2);
  2060.                                     ++j;
  2061.                                     ++block_idx;
  2062.                                     continue;
  2063.                                }
  2064.                                 
  2065.                             }
  2066.                             
  2067.                             bit_func(blk, arg_blk);
  2068.                             continue;
  2069.                        }
  2070.                    } // end of optimization branch...
  2071. */                   
  2072.                    combine_operation_with_block(block_idx, gap, blk, 
  2073.                                                 arg_blk, arg_gap,
  2074.                                                 opcode);
  2075.                 }
  2076.             } // for j
  2077.         } // for i
  2078.     }
  2079.     void combine_operation_with_block(unsigned nb,
  2080.                                       unsigned gap,
  2081.                                       bm::word_t* blk,
  2082.                                       const bm::word_t* arg_blk,
  2083.                                       int arg_gap,
  2084.                                       bm::operation opcode)
  2085.     {
  2086.          if (gap) // our block GAP-type
  2087.          {
  2088.              if (arg_gap)  // both blocks GAP-type
  2089.              {
  2090.                  gap_word_t tmp_buf[bm::gap_max_buff_len * 3]; // temporary result
  2091.              
  2092.                  gap_word_t* res;
  2093.                  switch (opcode)
  2094.                  {
  2095.                  case BM_AND:
  2096.                      res = gap_operation_and(BMGAP_PTR(blk), 
  2097.                                              BMGAP_PTR(arg_blk), 
  2098.                                              tmp_buf);
  2099.                      break;
  2100.                  case BM_OR:
  2101.                      res = gap_operation_or(BMGAP_PTR(blk), 
  2102.                                             BMGAP_PTR(arg_blk), 
  2103.                                             tmp_buf);
  2104.                      break;
  2105.                  case BM_SUB:
  2106.                      res = gap_operation_sub(BMGAP_PTR(blk), 
  2107.                                              BMGAP_PTR(arg_blk), 
  2108.                                              tmp_buf);
  2109.                      break;
  2110.                  case BM_XOR:
  2111.                      res = gap_operation_xor(BMGAP_PTR(blk), 
  2112.                                              BMGAP_PTR(arg_blk), 
  2113.                                              tmp_buf);
  2114.                      break;
  2115.                  default:
  2116.                      assert(0);
  2117.                      res = 0;
  2118.                  }
  2119.                  assert(res == tmp_buf);
  2120.                  unsigned res_len = bm::gap_length(res);
  2121.                  assert(!(res == tmp_buf && res_len == 0));
  2122.                  // if as a result of the operation gap block turned to zero
  2123.                  // we can now replace it with NULL
  2124.                  if (gap_is_all_zero(res, bm::gap_max_bits))
  2125.                  {
  2126.                      A::free_gap_block(BMGAP_PTR(blk), blockman_.glen());
  2127.                      blockman_.set_block(nb, 0);
  2128.                      blockman_.set_block_bit(nb);
  2129.                      return;
  2130.                  }
  2131.                  // mutation check
  2132.                  int level = gap_level(BMGAP_PTR(blk));
  2133.                  unsigned threshold = blockman_.glen(level)-4;
  2134.                  int new_level = gap_calc_level(res_len, blockman_.glen());
  2135.                  if (new_level == -1)
  2136.                  {
  2137.                      blockman_.convert_gap2bitset(nb, res);
  2138.                      return;
  2139.                  }
  2140.                  if (res_len > threshold)
  2141.                  {
  2142.                      set_gap_level(res, new_level);
  2143.                      gap_word_t* new_blk = 
  2144.                          blockman_.allocate_gap_block(new_level, res);
  2145.                      bm::word_t* p = (bm::word_t*)new_blk;
  2146.                      BMSET_PTRGAP(p);
  2147.                      blockman_.set_block(nb, p);
  2148.                      A::free_gap_block(BMGAP_PTR(blk), blockman_.glen());
  2149.                      return;
  2150.                  }
  2151.                  // gap opeartion result is in the temporary buffer
  2152.                  // we copy it back to the gap_block
  2153.                  set_gap_level(tmp_buf, level);
  2154.                  ::memcpy(BMGAP_PTR(blk), tmp_buf, res_len * sizeof(gap_word_t));
  2155.                  return;
  2156.              }
  2157.              else // argument is BITSET-type (own block is GAP)
  2158.              {
  2159.                  // since we can not combine blocks of mixed type
  2160.                  // we need to convert our block to bitset
  2161.                  
  2162.                  if (arg_blk == 0)  // Combining against an empty block
  2163.                  {
  2164.                     if (opcode == BM_OR || opcode == BM_SUB || opcode == BM_XOR)
  2165.                         return; // nothing to do
  2166.                         
  2167.                     if (opcode == BM_AND) // ("Value" AND  0) == 0
  2168.                     {
  2169.                         blockman_.set_block(nb, 0);
  2170.                         blockman_.set_block_bit(nb);
  2171.                         A::free_gap_block(BMGAP_PTR(blk), blockman_.glen());
  2172.                         return;
  2173.                     }
  2174.                  }
  2175.                  blk = blockman_.convert_gap2bitset(nb, BMGAP_PTR(blk));
  2176.              }
  2177.          } 
  2178.          else // our block is BITSET-type
  2179.          {
  2180.              if (arg_gap) // argument block is GAP-type
  2181.              {
  2182.                 if (IS_VALID_ADDR(blk))
  2183.                 {
  2184.                     // special case, maybe we can do the job without 
  2185.                     // converting the GAP argument to bitblock
  2186.                     switch (opcode)
  2187.                     {
  2188.                     case BM_OR:
  2189.                          gap_add_to_bitset(blk, BMGAP_PTR(arg_blk));
  2190.                          return;                         
  2191.                     case BM_SUB:
  2192.                          gap_sub_to_bitset(blk, BMGAP_PTR(arg_blk));
  2193.                          return;
  2194.                     case BM_XOR:
  2195.                          gap_xor_to_bitset(blk, BMGAP_PTR(arg_blk));
  2196.                          return;
  2197.                     case BM_AND:
  2198.                          gap_and_to_bitset(blk, BMGAP_PTR(arg_blk));
  2199.                          return;
  2200.                          
  2201.                     } // switch
  2202.                  }
  2203.                  
  2204.                  // the worst case we need to convert argument block to 
  2205.                  // bitset type.
  2206.                  gap_word_t* temp_blk = (gap_word_t*) blockman_.check_allocate_tempblock();
  2207.                  arg_blk = 
  2208.                      gap_convert_to_bitset_smart((bm::word_t*)temp_blk, 
  2209.                                                  BMGAP_PTR(arg_blk), 
  2210.                                                  bm::set_block_size,
  2211.                                                  bm::gap_max_bits);
  2212.              
  2213.              }   
  2214.          }
  2215.      
  2216.          // Now here we combine two plain bitblocks using supplied bit function.
  2217.          bm::word_t* dst = blk;
  2218.          bm::word_t* ret; 
  2219.          if (dst == 0 && arg_blk == 0)
  2220.          {
  2221.              return;
  2222.          }
  2223.          switch (opcode)
  2224.          {
  2225.          case BM_AND:
  2226.              ret = bit_operation_and(dst, arg_blk);
  2227.              goto copy_block;
  2228.          case BM_XOR:
  2229.              ret = bit_operation_xor(dst, arg_blk);
  2230.              if (ret && (ret == arg_blk) && IS_FULL_BLOCK(dst))
  2231.              {
  2232.                  ret = A::alloc_bit_block();
  2233. #ifdef BMVECTOPT
  2234.                 VECT_XOR_ARR_2_MASK(ret, 
  2235.                                     arg_blk, 
  2236.                                     arg_blk + bm::set_block_size, 
  2237.                                     bm::all_bits_mask);
  2238. #else
  2239.                  bm::wordop_t* dst_ptr = (wordop_t*)ret;
  2240.                  const bm::wordop_t* wrd_ptr = (wordop_t*) arg_blk;
  2241.                  const bm::wordop_t* wrd_end = 
  2242.                     (wordop_t*) (arg_blk + bm::set_block_size);
  2243.                  do
  2244.                  {
  2245.                      dst_ptr[0] = bm::all_bits_mask ^ wrd_ptr[0];
  2246.                      dst_ptr[1] = bm::all_bits_mask ^ wrd_ptr[1];
  2247.                      dst_ptr[2] = bm::all_bits_mask ^ wrd_ptr[2];
  2248.                      dst_ptr[3] = bm::all_bits_mask ^ wrd_ptr[3];
  2249.                      dst_ptr+=4;
  2250.                      wrd_ptr+=4;
  2251.                  } while (wrd_ptr < wrd_end);
  2252. #endif
  2253.                  break;
  2254.              }
  2255.              goto copy_block;
  2256.          case BM_OR:
  2257.              ret = bit_operation_or(dst, arg_blk);
  2258.          copy_block:
  2259.              if (ret && (ret == arg_blk) && !IS_FULL_BLOCK(ret))
  2260.              {
  2261.                 ret = A::alloc_bit_block();
  2262.                 bit_block_copy(ret, arg_blk);
  2263.              }
  2264.              break;
  2265.          case BM_SUB:
  2266.              ret = bit_operation_sub(dst, arg_blk);
  2267.              if (ret && ret == arg_blk)
  2268.              {
  2269.                  ret = A::alloc_bit_block();
  2270. #ifdef BMVECTOPT
  2271.                  VECT_ANDNOT_ARR_2_MASK(ret, 
  2272.                                         arg_blk,
  2273.                                         arg_blk + bm::set_block_size,
  2274.                                         bm::all_bits_mask);
  2275. #else
  2276.                  bm::wordop_t* dst_ptr = (wordop_t*)ret;
  2277.                  const bm::wordop_t* wrd_ptr = (wordop_t*) arg_blk;
  2278.                  const bm::wordop_t* wrd_end = 
  2279.                     (wordop_t*) (arg_blk + bm::set_block_size);
  2280.                  do
  2281.                  {
  2282.                      dst_ptr[0] = bm::all_bits_mask & ~wrd_ptr[0];
  2283.                      dst_ptr[1] = bm::all_bits_mask & ~wrd_ptr[1];
  2284.                      dst_ptr[2] = bm::all_bits_mask & ~wrd_ptr[2];
  2285.                      dst_ptr[3] = bm::all_bits_mask & ~wrd_ptr[3];
  2286.                      dst_ptr+=4;
  2287.                      wrd_ptr+=4;
  2288.                  } while (wrd_ptr < wrd_end);
  2289. #endif
  2290.              }
  2291.              break;
  2292.          default:
  2293.              assert(0);
  2294.              ret = 0;
  2295.          }
  2296.          if (ret != dst) // block mutation
  2297.          {
  2298.              blockman_.set_block(nb, ret);
  2299.              A::free_bit_block(dst);
  2300.          }
  2301.     }
  2302.     void combine_operation_with_block(unsigned nb,
  2303.                                       const bm::word_t* arg_blk,
  2304.                                       int arg_gap,
  2305.                                       bm::operation opcode)
  2306.     {
  2307.         bm::word_t* blk = const_cast<bm::word_t*>(get_block(nb));
  2308.         bool gap = BM_IS_GAP((*this), blk, nb);
  2309.         combine_operation_with_block(nb, gap, blk, arg_blk, arg_gap, opcode);
  2310.     }
  2311.     void combine_count_operation_with_block(unsigned nb,
  2312.                                             const bm::word_t* arg_blk,
  2313.                                             int arg_gap,
  2314.                                             bm::operation opcode)
  2315.     {
  2316.         const bm::word_t* blk = get_block(nb);
  2317.         bool gap = BM_IS_GAP((*this), blk, nb);
  2318.         combine_count_operation_with_block(nb, gap, blk, arg_blk, arg_gap, opcode);
  2319.     }
  2320.     /**
  2321.        brief Extends GAP block to the next level or converts it to bit block.
  2322.        param nb - Block's linear index.
  2323.        param blk - Blocks's pointer 
  2324.     */
  2325.     void extend_gap_block(unsigned nb, gap_word_t* blk)
  2326.     {
  2327.         blockman_.extend_gap_block(nb, blk);
  2328.     }
  2329. public:
  2330.     /** 
  2331.         Embedded class managing bit-blocks on very low level.
  2332.         Includes number of functor classes used in different bitset algorithms. 
  2333.     */
  2334.     class blocks_manager
  2335.     {
  2336.     friend class enumerator;
  2337.     friend class block_free_func;
  2338.     public:
  2339.         /** Base functor class */
  2340.         class bm_func_base
  2341.         {
  2342.         public:
  2343.             bm_func_base(blocks_manager& bman) : bm_(bman) {}
  2344.         protected:
  2345.             blocks_manager&  bm_;
  2346.         };
  2347.         /** Base functor class connected for "constant" functors*/
  2348.         class bm_func_base_const
  2349.         {
  2350.         public:
  2351.             bm_func_base_const(const blocks_manager& bman) : bm_(bman) {}
  2352.         protected:
  2353.             const blocks_manager&  bm_;
  2354.         };
  2355.         /** Base class for bitcounting functors */
  2356.         class block_count_base : public bm_func_base_const
  2357.         {
  2358.         protected:
  2359.             block_count_base(const blocks_manager& bm) 
  2360.                 : bm_func_base_const(bm) {}
  2361.             bm::id_t block_count(const bm::word_t* block, unsigned idx) const
  2362.             {
  2363.                 id_t count = 0;
  2364.                 if (IS_FULL_BLOCK(block))
  2365.                 {
  2366.                     count = bm::bits_in_block;
  2367.                 }
  2368.                 else
  2369.                 {
  2370.                     if (BM_IS_GAP(bm_, block, idx))
  2371.                     {
  2372.                         count = gap_bit_count(BMGAP_PTR(block));
  2373.                     }
  2374.                     else // bitset
  2375.                     {
  2376.                         count = 
  2377.                             bit_block_calc_count(block, 
  2378.                                                  block + bm::set_block_size);
  2379.                     }
  2380.                 }
  2381.                 return count;
  2382.             }
  2383.         };
  2384.         /** Bitcounting functor */
  2385.         class block_count_func : public block_count_base
  2386.         {
  2387.         public:
  2388.             block_count_func(const blocks_manager& bm) 
  2389.                 : block_count_base(bm), count_(0) {}
  2390.             bm::id_t count() const { return count_; }
  2391.             void operator()(const bm::word_t* block, unsigned idx)
  2392.             {
  2393.                 count_ += this->block_count(block, idx);
  2394.             }
  2395.         private:
  2396.             bm::id_t count_;
  2397.         };
  2398.         /** Bitcounting functor filling the block counts array*/
  2399.         class block_count_arr_func : public block_count_base
  2400.         {
  2401.         public:
  2402.             block_count_arr_func(const blocks_manager& bm, unsigned* arr) 
  2403.                 : block_count_base(bm), arr_(arr), last_idx_(0) 
  2404.             {
  2405.                 arr_[0] = 0;
  2406.             }
  2407.             void operator()(const bm::word_t* block, unsigned idx)
  2408.             {
  2409.                 while (++last_idx_ < idx)
  2410.                 {
  2411.                     arr_[last_idx_] = 0;
  2412.                 }
  2413.                 arr_[idx] = this->block_count(block, idx);
  2414.                 last_idx_ = idx;
  2415.             }
  2416.             unsigned last_block() const { return last_idx_; }
  2417.         private:
  2418.             unsigned*  arr_;
  2419.             unsigned   last_idx_;
  2420.         };
  2421.         /** bit value change counting functor */
  2422.         class block_count_change_func : public bm_func_base_const
  2423.         {
  2424.         public:
  2425.             block_count_change_func(const blocks_manager& bm) 
  2426.                 : bm_func_base_const(bm),
  2427.                   count_(0),
  2428.                   prev_block_border_bit_(0)
  2429.             {}
  2430.             bm::id_t block_count(const bm::word_t* block, unsigned idx)
  2431.             {
  2432.                 bm::id_t count = 0;
  2433.                 bm::id_t first_bit;
  2434.                 
  2435.                 if (IS_FULL_BLOCK(block) || (block == 0))
  2436.                 {
  2437.                     count = 1;
  2438.                     if (idx)
  2439.                     {
  2440.                         first_bit = block ? 1 : 0;
  2441.                         count -= !(prev_block_border_bit_ ^ first_bit);
  2442.                     }
  2443.                     prev_block_border_bit_ = block ? 1 : 0;
  2444.                 }
  2445.                 else
  2446.                 {
  2447.                     if (BM_IS_GAP(bm_, block, idx))
  2448.                     {
  2449.                         gap_word_t* gap_block = BMGAP_PTR(block);
  2450.                         count = gap_length(gap_block) - 1;
  2451.                         if (idx)
  2452.                         {
  2453.                             first_bit = gap_test(gap_block, 0);
  2454.                             count -= !(prev_block_border_bit_ ^ first_bit);
  2455.                         }
  2456.                             
  2457.                         prev_block_border_bit_ = 
  2458.                            gap_test(gap_block, gap_max_bits-1);
  2459.                     }
  2460.                     else // bitset
  2461.                     {
  2462.                         count = bit_block_calc_count_change(block,
  2463.                                                   block + bm::set_block_size);
  2464.                         if (idx)
  2465.                         {
  2466.                             first_bit = block[0] & 1;
  2467.                             count -= !(prev_block_border_bit_ ^ first_bit);
  2468.                         }
  2469.                         prev_block_border_bit_ = 
  2470.                             block[set_block_size-1] >> ((sizeof(block[0]) * 8) - 1);
  2471.                         
  2472.                     }
  2473.                 }
  2474.                 return count;
  2475.             }
  2476.             
  2477.             bm::id_t count() const { return count_; }
  2478.             void operator()(const bm::word_t* block, unsigned idx)
  2479.             {
  2480.                 count_ += block_count(block, idx);
  2481.             }
  2482.         private:
  2483.             bm::id_t   count_;
  2484.             bm::id_t   prev_block_border_bit_;
  2485.         };
  2486.         /** Functor detects if any bit set*/
  2487.         class block_any_func : public bm_func_base_const
  2488.         {
  2489.         public:
  2490.             block_any_func(const blocks_manager& bm) 
  2491.                 : bm_func_base_const(bm) 
  2492.             {}
  2493.             bool operator()(const bm::word_t* block, unsigned idx)
  2494.             {
  2495.                 if (IS_FULL_BLOCK(block)) return true;
  2496.                 if (BM_IS_GAP(bm_, block, idx)) // gap block
  2497.                 {
  2498.                     if (!gap_is_all_zero(BMGAP_PTR(block), bm::gap_max_bits))
  2499.                     {
  2500.                         return true;
  2501.                     }
  2502.                 }
  2503.                 else  // bitset
  2504.                 {
  2505.                     bm::wordop_t* blk1 = (wordop_t*)block;
  2506.                     bm::wordop_t* blk2 = 
  2507.                         (wordop_t*)(block + bm::set_block_size);
  2508.                     if (!bit_is_all_zero(blk1, blk2))
  2509.                     {
  2510.                         return true;
  2511.                     }
  2512.                 }
  2513.                 return false;
  2514.             }
  2515.         };
  2516.         /*! Change GAP level lengths functor */
  2517.         class gap_level_func : public bm_func_base
  2518.         {
  2519.         public:
  2520.             gap_level_func(blocks_manager& bm, const gap_word_t* glevel_len)
  2521.                 : bm_func_base(bm),
  2522.                   glevel_len_(glevel_len)
  2523.             {
  2524.                 assert(glevel_len);
  2525.             }
  2526.             void operator()(bm::word_t* block, unsigned idx)
  2527.             {
  2528.                 if (!BM_IS_GAP(bm_, block, idx))
  2529.                     return;
  2530.                 gap_word_t* gap_blk = BMGAP_PTR(block);
  2531.                 // TODO: Use the same code as in the optimize functor
  2532.                 if (gap_is_all_zero(gap_blk, bm::gap_max_bits))
  2533.                 {
  2534.                     this->bm_.set_block(idx, 0);
  2535.                     goto free_block;
  2536.                 }
  2537.                 else 
  2538.                     if (gap_is_all_one(gap_blk, bm::gap_max_bits))
  2539.                 {
  2540.                     this->bm_.set_block(idx, FULL_BLOCK_ADDR);
  2541.                 free_block:
  2542.                     A::free_gap_block(gap_blk, this->bm_.glen());
  2543.                     this->bm_.set_block_bit(idx);
  2544.                     return;
  2545.                 }
  2546.                 unsigned len = gap_length(gap_blk);
  2547.                 int level = gap_calc_level(len, glevel_len_);
  2548.                 if (level == -1)
  2549.                 {
  2550.                     bm::word_t* blk = A::alloc_bit_block();
  2551.                     this->bm_.set_block(idx, blk);
  2552.                     this->bm_.set_block_bit(idx);
  2553.                     gap_convert_to_bitset(blk, 
  2554.                                           gap_blk,
  2555.                                           bm::set_block_size);
  2556.                 }
  2557.                 else
  2558.                 {
  2559.                     gap_word_t* gap_blk_new = 
  2560.                         this->bm_.allocate_gap_block(level, gap_blk,
  2561.                                                      glevel_len_);
  2562.                     bm::word_t* p = (bm::word_t*) gap_blk_new;
  2563.                     BMSET_PTRGAP(p);
  2564.                     this->bm_.set_block(idx, p);
  2565.                 }
  2566.                 A::free_gap_block(gap_blk, this->bm_.glen());
  2567.             }
  2568.         private:
  2569.             const gap_word_t* glevel_len_;
  2570.         };
  2571.         /*! Bitblock optimization functor */
  2572.         class block_opt_func : public bm_func_base
  2573.         {
  2574.         public:
  2575.             block_opt_func(blocks_manager& bm, bm::word_t* temp_block) 
  2576.                 : bm_func_base(bm),
  2577.                   temp_block_(temp_block)
  2578.             {
  2579.                 assert(temp_block);
  2580.             }
  2581.             void operator()(bm::word_t* block, unsigned idx)
  2582.             {
  2583.                 if (IS_FULL_BLOCK(block)) return;
  2584.                 gap_word_t* gap_blk;
  2585.                 if (BM_IS_GAP(this->bm_, block, idx)) // gap block
  2586.                 {
  2587.                     gap_blk = BMGAP_PTR(block);
  2588.                     if (gap_is_all_zero(gap_blk, bm::gap_max_bits))
  2589.                     {
  2590.                         this->bm_.set_block(idx, 0);
  2591.                         goto free_block;
  2592.                     }
  2593.                     else 
  2594.                         if (gap_is_all_one(gap_blk, bm::gap_max_bits))
  2595.                     {
  2596.                         this->bm_.set_block(idx, FULL_BLOCK_ADDR);
  2597.                     free_block:
  2598.                         A::free_gap_block(gap_blk, this->bm_.glen());
  2599.                         this->bm_.set_block_bit(idx);
  2600.                     }
  2601.                 }
  2602.                 else // bit block
  2603.                 {
  2604.                     gap_word_t* tmp_gap_blk = (gap_word_t*)temp_block_;
  2605.                     *tmp_gap_blk = bm::gap_max_level << 1;
  2606.                     unsigned threashold = this->bm_.glen(bm::gap_max_level)-4;
  2607.                     unsigned len = bit_convert_to_gap(tmp_gap_blk, 
  2608.                                                       block, 
  2609.                                                       bm::gap_max_bits, 
  2610.                                                       threashold);
  2611.                     if (!len) return;
  2612.                     
  2613.                     // convertion successful
  2614.                     
  2615.                     A::free_bit_block(block);
  2616.                     // check if new gap block can be eliminated
  2617.                     if (gap_is_all_zero(tmp_gap_blk, bm::gap_max_bits))
  2618.                     {
  2619.                         this->bm_.set_block(idx, 0);
  2620.                     }
  2621.                     else if (gap_is_all_one(tmp_gap_blk, bm::gap_max_bits))
  2622.                     {
  2623.                         this->bm_.set_block(idx, FULL_BLOCK_ADDR);
  2624.                     }
  2625.                     else
  2626.                     {
  2627.                         int level = bm::gap_calc_level(len, this->bm_.glen());
  2628.                         gap_blk = this->bm_.allocate_gap_block(level,
  2629.                                                                tmp_gap_blk);
  2630.                         this->bm_.set_block(idx, (bm::word_t*)gap_blk);
  2631.                         this->bm_.set_block_gap(idx);
  2632.                     }
  2633.                     
  2634.          
  2635.                 }
  2636.             }
  2637.         private:
  2638.             bm::word_t*   temp_block_;
  2639.         };
  2640.         /** Bitblock invert functor */
  2641.         class block_invert_func : public bm_func_base
  2642.         {
  2643.         public:
  2644.             block_invert_func(blocks_manager& bm) 
  2645.                 : bm_func_base(bm) {}
  2646.             void operator()(bm::word_t* block, unsigned idx)
  2647.             {
  2648.                 if (!block)
  2649.                 {
  2650.                     this->bm_.set_block(idx, FULL_BLOCK_ADDR);
  2651.                 }
  2652.                 else
  2653.                 if (IS_FULL_BLOCK(block))
  2654.                 {
  2655.                     this->bm_.set_block(idx, 0);
  2656.                 }
  2657.                 else
  2658.                 {
  2659.                     if (BM_IS_GAP(this->bm_, block, idx)) // gap block
  2660.                     {
  2661.                         gap_invert(BMGAP_PTR(block));
  2662.                     }
  2663.                     else  // bit block
  2664.                     {
  2665.                         bm::wordop_t* wrd_ptr = (wordop_t*) block;
  2666.                         bm::wordop_t* wrd_end = 
  2667.                                 (wordop_t*) (block + bm::set_block_size);
  2668.                         bit_invert(wrd_ptr, wrd_end);
  2669.                     }
  2670.                 }
  2671.             }
  2672.         };
  2673.     private:
  2674.         /** Set block zero functor */
  2675.         class block_zero_func : public bm_func_base
  2676.         {
  2677.         public:
  2678.             block_zero_func(blocks_manager& bm, bool free_mem) 
  2679.             : bm_func_base(bm),
  2680.               free_mem_(free_mem)
  2681.             {}
  2682.             void operator()(bm::word_t* block, unsigned idx)
  2683.             {
  2684.                 if (IS_FULL_BLOCK(block))
  2685.                 {
  2686.                     this->bm_.set_block(idx, 0);
  2687.                 }
  2688.                 else
  2689.                 {
  2690.                     if (BM_IS_GAP(this->bm_, block, idx))
  2691.                     {
  2692.                         gap_set_all(BMGAP_PTR(block), bm::gap_max_bits, 0);
  2693.                     }
  2694.                     else  // BIT block
  2695.                     {
  2696.                         if (free_mem_)
  2697.                         {
  2698.                             A::free_bit_block(block);
  2699.                             this->bm_.set_block(idx, 0);
  2700.                         }
  2701.                         else
  2702.                         {
  2703.                             bit_block_set(block, 0);
  2704.                         }
  2705.                     }
  2706.                 }
  2707.             }
  2708.         private:
  2709.             bool free_mem_; //!< If "true" frees bitblocks memsets to '0'
  2710.         };
  2711.         /** Fill block with all-one bits functor */
  2712.         class block_one_func : public bm_func_base
  2713.         {
  2714.         public:
  2715.             block_one_func(blocks_manager& bm) : bm_func_base(bm) {}
  2716.             void operator()(bm::word_t* block, unsigned idx)
  2717.             {
  2718.                 if (!IS_FULL_BLOCK(block))
  2719.                 {
  2720.                     this->bm_.set_block_all_set(idx);
  2721.                 }
  2722.             }
  2723.         };
  2724.         /** Block deallocation functor */
  2725.         class block_free_func : public bm_func_base
  2726.         {
  2727.         public:
  2728.             block_free_func(blocks_manager& bm) : bm_func_base(bm) {}
  2729.             void operator()(bm::word_t* block, unsigned idx)
  2730.             {
  2731.                 if (BM_IS_GAP(this->bm_, block, idx)) // gap block
  2732.                 {
  2733.                     A::free_gap_block(BMGAP_PTR(block), this->bm_.glen());
  2734.                 }
  2735.                 else
  2736.                 {
  2737.                     A::free_bit_block(block);
  2738.                 }
  2739.                 idx = 0;
  2740.             }
  2741.         };
  2742.         /** Block copy functor */
  2743.         class block_copy_func : public bm_func_base
  2744.         {
  2745.         public:
  2746.             block_copy_func(blocks_manager& bm_target, const blocks_manager& bm_src) 
  2747.                 : bm_func_base(bm_target), bm_src_(bm_src) 
  2748.             {}
  2749.             void operator()(bm::word_t* block, unsigned idx)
  2750.             {
  2751.                 bool gap = bm_src_.is_block_gap(idx);
  2752.                 bm::word_t* new_blk;
  2753.                 if (gap)
  2754.                 {
  2755.                     bm::gap_word_t* gap_block = BMGAP_PTR(block); 
  2756.                     unsigned level = gap_level(gap_block);
  2757.                     new_blk = (bm::word_t*)A::alloc_gap_block
  2758.                         (level, this->bm_.glen());
  2759.                     int len = gap_length(BMGAP_PTR(block));
  2760.                     ::memcpy(new_blk, gap_block, len * sizeof(gap_word_t));
  2761.                     BMSET_PTRGAP(new_blk);
  2762.                 }
  2763.                 else
  2764.                 {
  2765.                     if (IS_FULL_BLOCK(block))
  2766.                     {
  2767.                         new_blk = block;
  2768.                     }
  2769.                     else
  2770.                     {
  2771.                         new_blk = A::alloc_bit_block();
  2772.                         bit_block_copy(new_blk, block);
  2773.                     }
  2774.                 }
  2775.                 this->bm_.set_block(idx, new_blk);
  2776.             }
  2777.         private:
  2778.             const blocks_manager&  bm_src_;
  2779.         };
  2780.     public:
  2781.         blocks_manager(const gap_word_t* glevel_len, bm::id_t max_bits)
  2782.             : blocks_(0),
  2783.               temp_block_(0)
  2784.         {
  2785.             ::memcpy(glevel_len_, glevel_len, sizeof(glevel_len_));
  2786.             if (!max_bits)  // working in ful range mode
  2787.             {
  2788.                 top_block_size_ = bm::set_array_size;
  2789.             }
  2790.             else  // limiting the working range
  2791.             {
  2792.                 top_block_size_ = 
  2793.                     max_bits / (bm::set_block_size * sizeof(bm::word_t) * bm::set_array_size * 8);
  2794.                 if (top_block_size_ < bm::set_array_size) ++top_block_size_;
  2795.             }
  2796.             // allocate first level descr. of blocks 
  2797.             blocks_ = (bm::word_t***)A::alloc_ptr(top_block_size_); 
  2798.             ::memset(blocks_, 0, top_block_size_ * sizeof(bm::word_t**));
  2799.             volatile const char* vp = _copyright<true>::_p;
  2800.             char c = *vp;
  2801.             c = 0;
  2802.         }
  2803.         blocks_manager(const blocks_manager& blockman)
  2804.             : blocks_(0),
  2805.               top_block_size_(blockman.top_block_size_),
  2806.          #ifdef BM_DISBALE_BIT_IN_PTR
  2807.               gap_flags_(blockman.gap_flags_),
  2808.          #endif
  2809.               temp_block_(0)
  2810.         {
  2811.             ::memcpy(glevel_len_, blockman.glevel_len_, sizeof(glevel_len_));
  2812.             blocks_ = (bm::word_t***)A::alloc_ptr(top_block_size_);
  2813.             ::memset(blocks_, 0, top_block_size_ * sizeof(bm::word_t**));
  2814.             blocks_manager* bm = 
  2815.                const_cast<blocks_manager*>(&blockman);
  2816.             bm::word_t*** blk_root = bm->blocks_root();
  2817.             block_copy_func copy_func(*this, blockman);
  2818.             for_each_nzblock(blk_root, top_block_size_, 
  2819.                                        bm::set_array_size, copy_func);
  2820.         }
  2821.         
  2822.         static void free_ptr(bm::word_t** ptr)
  2823.         {
  2824.             if (ptr) A::free_ptr(ptr);
  2825.         }
  2826.         ~blocks_manager()
  2827.         {
  2828.             A::free_bit_block(temp_block_);
  2829.             deinit_tree();
  2830.         }
  2831.         /**
  2832.            brief Finds block in 2-level blocks array  
  2833.            param nb - Index of block (logical linear number)
  2834.            return block adress or NULL if not yet allocated
  2835.         */
  2836.         bm::word_t* get_block(unsigned nb) const
  2837.         {
  2838.             unsigned block_idx = nb >> bm::set_array_shift;
  2839.             if (block_idx >= top_block_size_) return 0;
  2840.             bm::word_t** blk_blk = blocks_[block_idx];
  2841.             if (blk_blk)
  2842.             {
  2843.                return blk_blk[nb & bm::set_array_mask]; // equivalent of %
  2844.             }
  2845.             return 0; // not allocated
  2846.         }
  2847.         /**
  2848.            brief Finds block in 2-level blocks array
  2849.            param i - top level block index
  2850.            param j - second level block index
  2851.            return block adress or NULL if not yet allocated
  2852.         */
  2853.         const bm::word_t* get_block(unsigned i, unsigned j) const
  2854.         {
  2855.             if (i >= top_block_size_) return 0;
  2856.             const bm::word_t* const* blk_blk = blocks_[i];
  2857.             return (blk_blk == 0) ? 0 : blk_blk[j];
  2858.         }
  2859.         /**
  2860.            brief Function returns top-level block in 2-level blocks array
  2861.            param i - top level block index
  2862.            return block adress or NULL if not yet allocated
  2863.         */
  2864.         const bm::word_t* const * get_topblock(unsigned i) const
  2865.         {
  2866.             if (i >= top_block_size_) return 0;
  2867.             return blocks_[i];
  2868.         }
  2869.         
  2870.         /** 
  2871.             brief Returns root block in the tree.
  2872.         */
  2873.         bm::word_t*** get_rootblock() const
  2874.         {
  2875.             blocks_manager* bm = 
  2876.                const_cast<blocks_manager*>(this);
  2877.             return bm->blocks_root();
  2878.         }
  2879.         void set_block_all_set(unsigned nb)
  2880.         {
  2881.             bm::word_t* block = this->get_block(nb);
  2882.             if (BM_IS_GAP((*this), block, nb))
  2883.             {
  2884.                 A::free_gap_block(BMGAP_PTR(block), glevel_len_);
  2885.             }
  2886.             else
  2887.             {
  2888.                 A::free_bit_block(block);
  2889.             }
  2890.             set_block(nb, const_cast<bm::word_t*>(FULL_BLOCK_ADDR));
  2891.           // If we keep block type flag in pointer itself we dp not need 
  2892.           // to clear gap bit 
  2893.           #ifdef BM_DISBALE_BIT_IN_PTR
  2894.             set_block_bit(nb);    
  2895.           #endif
  2896.         }
  2897.         /** 
  2898.             Function checks if block is not yet allocated, allocates it and sets to
  2899.             all-zero or all-one bits. 
  2900.     
  2901.             If content_flag == 1 (ALLSET block) requested and taken block is already ALLSET,
  2902.             function will return NULL
  2903.             initial_block_type and actual_block_type : 0 - bitset, 1 - gap
  2904.         */
  2905.         bm::word_t* check_allocate_block(unsigned nb, 
  2906.                                          unsigned content_flag,
  2907.                                          int      initial_block_type,
  2908.                                          int*     actual_block_type,
  2909.                                          bool     allow_null_ret=true)
  2910.         {
  2911.             bm::word_t* block = this->get_block(nb);
  2912.             if (!IS_VALID_ADDR(block)) // NULL block or ALLSET
  2913.             {
  2914.                 // if we wanted ALLSET and requested block is ALLSET return NULL
  2915.                 unsigned block_flag = IS_FULL_BLOCK(block);
  2916.                 *actual_block_type = initial_block_type;
  2917.                 if (block_flag == content_flag && allow_null_ret)
  2918.                 {
  2919.                     return 0; // it means nothing to do for the caller
  2920.                 }
  2921.                 if (initial_block_type == 0) // bitset requested
  2922.                 {
  2923.                     block = A::alloc_bit_block();
  2924.                     // initialize block depending on its previous status
  2925.                     bit_block_set(block, block_flag ? 0xFF : 0);
  2926.                     set_block(nb, block);
  2927.                 }
  2928.                 else // gap block requested
  2929.                 {
  2930.                     bm::gap_word_t* gap_block = allocate_gap_block(0);
  2931.                     gap_set_all(gap_block, bm::gap_max_bits, block_flag);
  2932.                     set_block(nb, (bm::word_t*)gap_block);
  2933.                     set_block_gap(nb);
  2934.                     return (bm::word_t*)gap_block;
  2935.                 }
  2936.             }
  2937.             else // block already exists
  2938.             {
  2939.                 *actual_block_type = BM_IS_GAP((*this), block, nb);
  2940.             }
  2941.             return block;
  2942.         }
  2943.         /*! @brief Fills all blocks with 0.
  2944.             @param free_mem - if true function frees the resources
  2945.         */
  2946.         void set_all_zero(bool free_mem)
  2947.         {
  2948.             block_zero_func zero_func(*this, free_mem);
  2949.             for_each_nzblock(blocks_, top_block_size_,
  2950.                                       bm::set_array_size, zero_func);
  2951.         }
  2952.         /*! Replaces all blocks with ALL_ONE block.
  2953.         */
  2954.         void set_all_one()
  2955.         {
  2956.             block_one_func func(*this);
  2957.             for_each_block(blocks_, top_block_size_, 
  2958.                                     bm::set_array_size, func);
  2959.         }
  2960.         /*! 
  2961.             Places new block into descriptors table, returns old block's address.
  2962.             Old block is not deleted.
  2963.         */
  2964.         bm::word_t* set_block(unsigned nb, bm::word_t* block)
  2965.         {
  2966.             bm::word_t* old_block;
  2967.             register unsigned nblk_blk = nb >> bm::set_array_shift;
  2968.             // If first level array not yet allocated, allocate it and
  2969.             // assign block to it
  2970.             if (blocks_[nblk_blk] == 0) 
  2971.             {
  2972.                 blocks_[nblk_blk] = (bm::word_t**)A::alloc_ptr();
  2973.                 ::memset(blocks_[nblk_blk], 0, 
  2974.                     bm::set_array_size * sizeof(bm::word_t*));
  2975.                 old_block = 0;
  2976.             }
  2977.             else
  2978.             {
  2979.                 old_block = blocks_[nblk_blk][nb & bm::set_array_mask];
  2980.             }
  2981.             // NOTE: block will be replaced without freeing,
  2982.             // potential memory leak may lay here....
  2983.             blocks_[nblk_blk][nb & bm::set_array_mask] = block; // equivalent to %
  2984.             return old_block;
  2985.         }
  2986.         /** 
  2987.            brief Converts block from type gap to conventional bitset block.
  2988.            param nb - Block's index. 
  2989.            param gap_block - Pointer to the gap block, 
  2990.                               if NULL block nb will be taken
  2991.            return new gap block's memory
  2992.         */
  2993.         bm::word_t* convert_gap2bitset(unsigned nb, gap_word_t* gap_block=0)
  2994.         {
  2995.             bm::word_t* block = this->get_block(nb);
  2996.             if (gap_block == 0)
  2997.             {
  2998.                 gap_block = BMGAP_PTR(block);
  2999.             }
  3000.             assert(IS_VALID_ADDR((bm::word_t*)gap_block));
  3001.             assert(is_block_gap(nb)); // must be GAP type
  3002.             bm::word_t* new_block = A::alloc_bit_block();
  3003.             gap_convert_to_bitset(new_block, gap_block, bm::set_block_size);
  3004.             // new block will replace the old one(no deletion)
  3005.             set_block(nb, new_block); 
  3006.             A::free_gap_block(BMGAP_PTR(block), glen());
  3007.           // If GAP flag is in block pointer no need to clean the gap bit twice
  3008.           #ifdef BM_DISBALE_BIT_IN_PTR
  3009.             set_block_bit(nb);
  3010.           #endif
  3011.             return new_block;
  3012.         }
  3013.         /**
  3014.            brief Extends GAP block to the next level or converts it to bit block.
  3015.            param nb - Block's linear index.
  3016.            param blk - Blocks's pointer 
  3017.         */
  3018.         void extend_gap_block(unsigned nb, gap_word_t* blk)
  3019.         {
  3020.             unsigned level = bm::gap_level(blk);
  3021.             unsigned len = bm::gap_length(blk);
  3022.             if (level == bm::gap_max_level || len >= gap_max_buff_len)
  3023.             {
  3024.                 convert_gap2bitset(nb);
  3025.             }
  3026.             else
  3027.             {
  3028.                 bm::word_t* new_blk = (bm::word_t*)allocate_gap_block(++level, blk);
  3029.                 BMSET_PTRGAP(new_blk);
  3030.                 set_block(nb, new_blk);
  3031.                 A::free_gap_block(blk, glen());
  3032.             }
  3033.         }
  3034.         bool is_block_gap(unsigned nb) const 
  3035.         {
  3036.          #ifdef BM_DISBALE_BIT_IN_PTR
  3037.             return gap_flags_.test(nb)!=0;
  3038.          #else
  3039.             bm::word_t* block = get_block(nb);
  3040.             return BMPTR_TESTBIT0(block) != 0;
  3041.          #endif
  3042.         }
  3043.         void set_block_bit(unsigned nb) 
  3044.         { 
  3045.          #ifdef BM_DISBALE_BIT_IN_PTR
  3046.             gap_flags_.set(nb, false);
  3047.          #else
  3048.             bm::word_t* block = get_block(nb);
  3049.             block = (bm::word_t*) BMPTR_CLEARBIT0(block);
  3050.             set_block(nb, block);
  3051.          #endif
  3052.         }
  3053.         void set_block_gap(unsigned nb) 
  3054.         {
  3055.          #ifdef BM_DISBALE_BIT_IN_PTR
  3056.             gap_flags_.set(nb);
  3057.          #else
  3058.             bm::word_t* block = get_block(nb);
  3059.             block = (bm::word_t*)BMPTR_SETBIT0(block);
  3060.             set_block(nb, block);
  3061.          #endif
  3062.         }
  3063.         /**
  3064.            fn bool bm::bvector::blocks_manager::is_block_zero(unsigned nb, bm::word_t* blk)
  3065.            brief Checks all conditions and returns true if block consists of only 0 bits
  3066.            param nb - Block's linear index.
  3067.            param blk - Blocks's pointer 
  3068.            returns true if all bits are in the block are 0.
  3069.         */
  3070.         bool is_block_zero(unsigned nb, const bm::word_t* blk) const
  3071.         {
  3072.            if (blk == 0) return true;
  3073.            if (BM_IS_GAP((*this), blk, nb)) // GAP
  3074.            {
  3075.                gap_word_t* b = BMGAP_PTR(blk);
  3076.                return gap_is_all_zero(b, bm::gap_max_bits);
  3077.            }
  3078.    
  3079.            // BIT
  3080.            for (unsigned i = 0; i <  bm::set_block_size; ++i)
  3081.            {
  3082.                if (blk[i] != 0)
  3083.                   return false;
  3084.            }
  3085.            return true;
  3086.         }
  3087.         /**
  3088.            brief Checks if block has only 1 bits
  3089.            param nb - Index of the block.
  3090.            param blk - Block's pointer
  3091.            return true if block consists of 1 bits.
  3092.         */
  3093.         bool is_block_one(unsigned nb, const bm::word_t* blk) const
  3094.         {
  3095.            if (blk == 0) return false;
  3096.            if (BM_IS_GAP((*this), blk, nb)) // GAP
  3097.            {
  3098.                gap_word_t* b = BMGAP_PTR(blk);
  3099.                return gap_is_all_one(b, bm::gap_max_bits);
  3100.            }
  3101.    
  3102.            // BIT block
  3103.            if (IS_FULL_BLOCK(blk))
  3104.            {
  3105.               return true;
  3106.            }
  3107.            return is_bits_one((wordop_t*)blk, (wordop_t*)(blk + bm::set_block_size));
  3108.         }
  3109.         /*! Returns temporary block, allocates if needed. */
  3110.         bm::word_t* check_allocate_tempblock()
  3111.         {
  3112.             return temp_block_ ? temp_block_ : (temp_block_ = A::alloc_bit_block());
  3113.         }
  3114.         /*! Assigns new GAP lengths vector */
  3115.         void set_glen(const gap_word_t* glevel_len)
  3116.         {
  3117.             ::memcpy(glevel_len_, glevel_len, sizeof(glevel_len_));
  3118.         }
  3119.         bm::gap_word_t* allocate_gap_block(unsigned level, 
  3120.                                            gap_word_t* src = 0,
  3121.                                            const gap_word_t* glevel_len = 0) const
  3122.         {
  3123.            if (!glevel_len)
  3124.                glevel_len = glevel_len_;
  3125.            gap_word_t* ptr = A::alloc_gap_block(level, glevel_len);
  3126.            if (src)
  3127.            {
  3128.                 unsigned len = gap_length(src);
  3129.                 ::memcpy(ptr, src, len * sizeof(gap_word_t));
  3130.                 // Reconstruct the mask word using the new level code.
  3131.                 *ptr = ((len-1) << 3) | (level << 1) | (*src & 1);
  3132.            }
  3133.            else
  3134.            {
  3135.                *ptr = level << 1;
  3136.            }
  3137.            return ptr;
  3138.         }
  3139.         unsigned mem_used() const
  3140.         {
  3141.            unsigned mem_used = sizeof(*this);
  3142.            mem_used += temp_block_ ? sizeof(word_t) * bm::set_block_size : 0;
  3143.            mem_used += sizeof(bm::word_t**) * top_block_size_;
  3144.          #ifdef BM_DISBALE_BIT_IN_PTR
  3145.            mem_used += gap_flags_.mem_used() - sizeof(gap_flags_);
  3146.          #endif
  3147.            for (unsigned i = 0; i < top_block_size_; ++i)
  3148.            {
  3149.               mem_used += blocks_[i] ? sizeof(void*) * bm::set_array_size : 0;
  3150.            }
  3151.            return mem_used;
  3152.         }
  3153.         /** Returns true if second level block pointer is 0.
  3154.         */
  3155.         bool is_subblock_null(unsigned nsub) const
  3156.         {
  3157.            return blocks_[nsub] == NULL;
  3158.         }
  3159.         bm::word_t***  blocks_root()
  3160.         {
  3161.             return blocks_;
  3162.         }
  3163.         /*! brief Returns current GAP level vector
  3164.         */
  3165.         const gap_word_t* glen() const
  3166.         {
  3167.             return glevel_len_;
  3168.         }
  3169.         /*! brief Returns GAP level length for specified level
  3170.             param level - level number
  3171.         */
  3172.         unsigned glen(unsigned level) const
  3173.         {
  3174.             return glevel_len_[level];
  3175.         }
  3176.         /*! brief Swaps content 
  3177.             param bm  another blocks manager
  3178.         */
  3179.         void swap(blocks_manager& bm)
  3180.         {
  3181.             bm::word_t*** btmp = blocks_;
  3182.             blocks_ = bm.blocks_;
  3183.             bm.blocks_ = btmp;
  3184.          #ifdef BM_DISBALE_BIT_IN_PTR
  3185.             gap_flags_.swap(bm.gap_flags_);
  3186.          #endif
  3187.             gap_word_t gltmp[bm::gap_levels];
  3188.             
  3189.             ::memcpy(gltmp, glevel_len_, sizeof(glevel_len_));
  3190.             ::memcpy(glevel_len_, bm.glevel_len_, sizeof(glevel_len_));
  3191.             ::memcpy(bm.glevel_len_, gltmp, sizeof(glevel_len_));
  3192.         }
  3193.         /*! brief Returns size of the top block array in the tree 
  3194.         */
  3195.         unsigned top_block_size() const
  3196.         {
  3197.             return top_block_size_;
  3198.         }
  3199.         /*! brief Sets ne top level block size.
  3200.         */
  3201.         void set_top_block_size(unsigned value)
  3202.         {
  3203.             assert(value);
  3204.             if (value == top_block_size_) return;
  3205.             deinit_tree();
  3206.             top_block_size_ = value;
  3207.             // allocate first level descr. of blocks 
  3208.             blocks_ = (bm::word_t***)A::alloc_ptr(top_block_size_); 
  3209.             ::memset(blocks_, 0, top_block_size_ * sizeof(bm::word_t**));
  3210.         }
  3211.     private:
  3212.         void operator =(const blocks_manager&);
  3213.         void deinit_tree()
  3214.         {
  3215.             if (blocks_ == 0) return;
  3216.             block_free_func  free_func(*this);
  3217.             for_each_nzblock(blocks_, top_block_size_, 
  3218.                                       bm::set_array_size, free_func);
  3219.             bmfor_each(blocks_, blocks_ + top_block_size_, free_ptr);
  3220.             A::free_ptr(blocks_, top_block_size_);
  3221.         }
  3222.     private:
  3223.         typedef A  alloc;
  3224.         /// Tree of blocks.
  3225.         bm::word_t***                          blocks_;
  3226.         /// Size of the top level block array in blocks_ tree
  3227.         unsigned                               top_block_size_;
  3228.      #ifdef BM_DISBALE_BIT_IN_PTR
  3229.         /// mini bitvector used to indicate gap blocks
  3230.         MS                                     gap_flags_;
  3231.      #endif
  3232.         /// Temp block.
  3233.         bm::word_t*                            temp_block_; 
  3234.         /// vector defines gap block lengths for different levels 
  3235.         gap_word_t                             glevel_len_[gap_levels];
  3236.     };
  3237.     
  3238.     const blocks_manager& get_blocks_manager() const
  3239.     {
  3240.         return blockman_;
  3241.     }
  3242.     blocks_manager& get_blocks_manager()
  3243.     {
  3244.         return blockman_;
  3245.     }
  3246. private:
  3247. // This block defines two additional hidden variables used for bitcount
  3248. // optimization, in rare cases can make bitvector thread unsafe.
  3249. #ifdef BMCOUNTOPT
  3250.     mutable id_t      count_;            //!< number of bits "ON" in the vector
  3251.     mutable bool      count_is_valid_;   //!< actualization flag
  3252. #endif
  3253.     blocks_manager    blockman_;         //!< bitblocks manager
  3254.     strategy          new_blocks_strat_; //!< blocks allocation strategy.
  3255. };
  3256. //---------------------------------------------------------------------
  3257. template<class A, class MS> 
  3258. inline bvector<A, MS> operator& (const bvector<A, MS>& v1,
  3259.                                  const bvector<A, MS>& v2)
  3260. {
  3261.     bvector<A, MS> ret(v1);
  3262.     ret.bit_and(v2);
  3263.     return ret;
  3264. }
  3265. //---------------------------------------------------------------------
  3266. template<class A, class MS> 
  3267. inline bvector<A, MS> operator| (const bvector<A, MS>& v1,
  3268.                                  const bvector<A>& v2)
  3269. {   
  3270.     bvector<A, MS> ret(v1);
  3271.     ret.bit_or(v2);
  3272.     return ret;
  3273. }
  3274. //---------------------------------------------------------------------
  3275. template<class A, class MS> 
  3276. inline bvector<A, MS> operator^ (const bvector<A, MS>& v1,
  3277.                                  const bvector<A, MS>& v2)
  3278. {
  3279.     bvector<A, MS> ret(v1);
  3280.     ret.bit_xor(v2);
  3281.     return ret;
  3282. }
  3283. //---------------------------------------------------------------------
  3284. template<class A, class MS> 
  3285. inline bvector<A, MS> operator- (const bvector<A, MS>& v1,
  3286.                                  const bvector<A, MS>& v2)
  3287. {
  3288.     bvector<A, MS> ret(v1);
  3289.     ret.bit_sub(v2);
  3290.     return ret;
  3291. }
  3292. // -----------------------------------------------------------------------
  3293. template<typename A, typename MS> 
  3294. void bvector<A, MS>::calc_stat(typename bvector<A, MS>::statistics* st) const
  3295. {
  3296.     st->bit_blocks = st->gap_blocks 
  3297.                    = st->max_serialize_mem 
  3298.                    = st->memory_used = 0;
  3299.     ::memcpy(st->gap_levels, 
  3300.              blockman_.glen(), sizeof(gap_word_t) * bm::gap_levels);
  3301.     unsigned empty_blocks = 0;
  3302.     unsigned blocks_memory = 0;
  3303.     gap_word_t* gapl_ptr = st->gap_length;
  3304.     st->max_serialize_mem = sizeof(id_t) * 4;
  3305.     unsigned block_idx = 0;
  3306.     // Walk the blocks, calculate statistics.
  3307.     for (unsigned i = 0; i < blockman_.top_block_size(); ++i)
  3308.     {
  3309.         const bm::word_t* const* blk_blk = blockman_.get_topblock(i);
  3310.         if (!blk_blk) 
  3311.         {
  3312.             block_idx += bm::set_array_size;
  3313.             st->max_serialize_mem += sizeof(unsigned) + 1;
  3314.             continue;
  3315.         }
  3316.         for (unsigned j = 0;j < bm::set_array_size; ++j, ++block_idx)
  3317.         {
  3318.             const bm::word_t* blk = blk_blk[j];
  3319.             if (IS_VALID_ADDR(blk))
  3320.             {
  3321.                 st->max_serialize_mem += empty_blocks << 2;
  3322.                 empty_blocks = 0;
  3323.                 if (BM_IS_GAP(blockman_, blk, block_idx)) // gap block
  3324.                 {
  3325.                     ++(st->gap_blocks);
  3326.                     bm::gap_word_t* gap_blk = BMGAP_PTR(blk);
  3327.                     unsigned mem_used = 
  3328.                         bm::gap_capacity(gap_blk, blockman_.glen()) 
  3329.                         * sizeof(gap_word_t);
  3330.                     *gapl_ptr = gap_length(gap_blk);
  3331.                     st->max_serialize_mem += *gapl_ptr * sizeof(gap_word_t);
  3332.                     blocks_memory += mem_used;
  3333.                     ++gapl_ptr;
  3334.                 }
  3335.                 else // bit block
  3336.                 {
  3337.                     ++(st->bit_blocks);
  3338.                     unsigned mem_used = sizeof(bm::word_t) * bm::set_block_size;
  3339.                     st->max_serialize_mem += mem_used;
  3340.                     blocks_memory += mem_used;
  3341.                 }
  3342.             }
  3343.             else
  3344.             {
  3345.                 ++empty_blocks;
  3346.             }
  3347.         }
  3348.     }  
  3349.     st->max_serialize_mem += st->max_serialize_mem / 10; // 10% increment
  3350.     // Calc size of different odd and temporary things.
  3351.     st->memory_used += sizeof(*this) - sizeof(blockman_);
  3352.     st->memory_used += blockman_.mem_used();
  3353.     st->memory_used += blocks_memory;
  3354. }
  3355. // -----------------------------------------------------------------------
  3356. template<class A, class MS> void bvector<A, MS>::stat(unsigned blocks) const
  3357. {
  3358.     register bm::id_t count = 0;
  3359.     int printed = 0;
  3360.     if (!blocks)
  3361.     {
  3362.         blocks = bm::set_total_blocks;
  3363.     }
  3364.     unsigned nb;
  3365.     for (nb = 0; nb < blocks; ++nb)
  3366.     {
  3367.         register const bm::word_t* blk = blockman_.get_block(nb);
  3368.         if (blk == 0)
  3369.         {
  3370.            continue;
  3371.         }
  3372.         if (IS_FULL_BLOCK(blk))
  3373.         {
  3374.            if (blockman_.is_block_gap(nb)) // gap block
  3375.            {
  3376.                printf("[Alert!%i]", nb);
  3377.                assert(0);
  3378.            }
  3379.            
  3380.            unsigned start = nb; 
  3381.            for(unsigned i = nb+1; i < bm::set_total_blocks; ++i, ++nb)
  3382.            {
  3383.                blk = blockman_.get_block(nb);
  3384.                if (IS_FULL_BLOCK(blk))
  3385.                {
  3386.                  if (blockman_.is_block_gap(nb)) // gap block
  3387.                  {
  3388.                      printf("[Alert!%i]", nb);
  3389.                      assert(0);
  3390.                      --nb;
  3391.                      break;
  3392.                  }
  3393.                }
  3394.                else
  3395.                {
  3396.                   --nb;
  3397.                   break;
  3398.                }
  3399.            }
  3400. printf("{F.%i:%i}",start, nb);
  3401.             ++printed;
  3402. /*
  3403.             count += bm::SET_BLOCK_MASK + 1;
  3404.             register const bm::word_t* blk_end = blk + bm::SET_BLOCK_SIZE;
  3405.             unsigned count2 = ::bit_block_calc_count(blk, blk_end);
  3406.             assert(count2 == bm::SET_BLOCK_MASK + 1);
  3407. */
  3408.         }
  3409.         else
  3410.         {
  3411.             if (blockman_.is_block_gap(nb)) // gap block
  3412.             {
  3413.                unsigned bc = gap_bit_count(BMGAP_PTR(blk));
  3414.                unsigned sum = gap_control_sum(BMGAP_PTR(blk));
  3415.                unsigned level = gap_level(BMGAP_PTR(blk));
  3416.                 count += bc;
  3417. printf("[ GAP %i=%i:%i ]", nb, bc, level);
  3418. //printf("%i", count);
  3419.                if (sum != bm::gap_max_bits)
  3420.                {
  3421.                     printf("<=*");
  3422.                }
  3423.                 ++printed;
  3424.             }
  3425.             else // bitset
  3426.             {
  3427.                 const bm::word_t* blk_end = blk + bm::set_block_size;
  3428.                 unsigned bc = bit_block_calc_count(blk, blk_end);
  3429.                 count += bc;
  3430. printf("( BIT %i=%i )", nb, bc);
  3431. //printf("%i", count);
  3432.                 ++printed;
  3433.                 
  3434.             }
  3435.         }
  3436.         if (printed == 10)
  3437.         {
  3438.             printed = 0;
  3439.             printf("n");
  3440.         }
  3441.     } // for nb
  3442. //    printf("nCOUNT=%in", count);
  3443.     printf("n");
  3444. }
  3445. //---------------------------------------------------------------------
  3446. } // namespace
  3447. #include "bmundef.h"
  3448. #endif