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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: bmfunc.h,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:39:08  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.3
  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 BMFUNC__H__INCLUDED__
  29. #define BMFUNC__H__INCLUDED__
  30. #include <memory.h>
  31. #ifdef _MSC_VER
  32. # pragma warning( disable: 4146 )
  33. #endif
  34. namespace bm
  35. {
  36. /*! @defgroup gapfunc GAP functions
  37.  *  GAP functions implement different opereations on GAP compressed blocks
  38.  *  and serve as a minimal building blocks.
  39.  *
  40.  */
  41. /*! @defgroup bitfunc BIT functions
  42.  *  Bit functions implement different opereations on bit blocks
  43.  *  and serve as a minimal building blocks.
  44.  *
  45.  */
  46. /*! @brief Default GAP lengths table.
  47.     @ingroup gapfunc
  48. */
  49. template<bool T> struct gap_len_table
  50. {
  51.     static const gap_word_t _len[bm::gap_levels];
  52. };
  53. template<bool T>
  54. const gap_word_t gap_len_table<T>::_len[] = 
  55.                 { 128, 256, 512, bm::gap_max_buff_len }; 
  56. /*! @brief Alternative GAP lengths table. 
  57.     Good for for memory saver mode and very sparse bitsets.
  58.     @ingroup gapfunc
  59. */
  60. template<bool T> struct gap_len_table_min
  61. {
  62.     static const gap_word_t _len[bm::gap_levels];
  63. };
  64. template<bool T>
  65. const gap_word_t gap_len_table_min<T>::_len[] = 
  66.                                 { 32, 96, 128, 512 }; 
  67. //---------------------------------------------------------------------
  68. /** Structure to aid in counting bits
  69.     table contains count of bits in 0-255 diapason of numbers
  70.    @ingroup bitfunc
  71. */
  72. template<bool T> struct bit_count_table 
  73. {
  74.   static const unsigned char _count[256];
  75. };
  76. template<bool T>
  77. const unsigned char bit_count_table<T>::_count[] = {
  78.     0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
  79.     1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  80.     1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  81.     2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  82.     1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
  83.     2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  84.     2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
  85.     3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
  86. };
  87. //---------------------------------------------------------------------
  88. /** Structure keeps all-left/right ON bits masks. 
  89.     @ingroup bitfunc 
  90. */
  91. template<bool T> struct block_set_table
  92. {
  93.     static const unsigned _left[32];
  94.     static const unsigned _right[32];
  95. };
  96. template<bool T>
  97. const unsigned block_set_table<T>::_left[] = {
  98.     0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff,
  99.     0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff, 0x1ffff, 0x3ffff, 0x7ffff,
  100.     0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff,
  101.     0x7ffffff, 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff
  102. };
  103. template<bool T>
  104. const unsigned block_set_table<T>::_right[] = {
  105.     0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8, 0xfffffff0,
  106.     0xffffffe0, 0xffffffc0, 0xffffff80, 0xffffff00, 0xfffffe00,
  107.     0xfffffc00, 0xfffff800, 0xfffff000, 0xffffe000, 0xffffc000,
  108.     0xffff8000, 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
  109.     0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, 0xff000000,
  110.     0xfe000000, 0xfc000000, 0xf8000000, 0xf0000000, 0xe0000000,
  111.     0xc0000000, 0x80000000
  112. };
  113. /** Structure keeps index of first ON bit for every byte.  
  114.     @ingroup bitfunc 
  115. */
  116. template<bool T> struct first_bit_table
  117. {
  118.     static const char _idx[256];
  119. };
  120. template<bool T>
  121. const char first_bit_table<T>::_idx[] = {
  122.     -1,
  123.     0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,
  124.     1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1, 0,2,0,1,0,3,0,
  125.     1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,
  126.     0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,
  127.     2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
  128.     0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,
  129.     1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,
  130.     0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,
  131.     3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0 
  132. };
  133. /*! 
  134. Define calculates number of 1 bits in 32-bit word.
  135.     @ingroup bitfunc 
  136. */
  137. #define BM_INCWORD_BITCOUNT(cnt, w) cnt += 
  138.     bm::bit_count_table<true>::_count[(unsigned char)(w)] + 
  139.     bm::bit_count_table<true>::_count[(unsigned char)((w) >> 8)] + 
  140.     bm::bit_count_table<true>::_count[(unsigned char)((w) >> 16)] + 
  141.     bm::bit_count_table<true>::_count[(unsigned char)((w) >> 24)];
  142. #ifdef BM64OPT
  143. /*! 
  144. Function calculates number of 1 bits in 64-bit word.
  145.     @ingroup bitfunc 
  146. */
  147. inline bm::id_t word_bitcount64(bm::id64_t w)
  148. {
  149.     w = (w & 0x5555555555555555LU) + (w >> 1 & 0x5555555555555555LU);
  150.     w = (w & 0x3333333333333333LU) + (w >> 2 & 0x3333333333333333LU);
  151.     w = w + (w >> 4) & 0x0F0F0F0F0F0F0F0FLU;
  152.     w = w + (w >> 8);
  153.     w = w + (w >> 16);
  154.     w = w + (w >> 32) & 0x0000007F;
  155.     return (bm::id_t)w;
  156. }
  157. #endif
  158. //---------------------------------------------------------------------
  159. /**
  160.     Bit operations enumeration.
  161. */
  162. enum operation
  163. {
  164.     BM_AND = 0,
  165.     BM_OR,
  166.     BM_SUB,
  167.     BM_XOR
  168. };
  169. //---------------------------------------------------------------------
  170. /** 
  171.     Structure carries pointer on bit block with all bits 1
  172.     @ingroup bitfunc 
  173. */
  174. template<bool T> struct all_set
  175. {
  176.     struct all_set_block
  177.     {
  178.         bm::word_t _p[bm::set_block_size];
  179.         all_set_block()
  180.         {
  181.             ::memset(_p, 0xFF, sizeof(_p));
  182.         }
  183.     };
  184.     static all_set_block  _block;
  185. };
  186. template<bool T> typename all_set<T>::all_set_block all_set<T>::_block;
  187. //---------------------------------------------------------------------
  188. /*! 
  189.    brief Lexicographical comparison of two words as bit strings.
  190.    Auxiliary implementation for testing and reference purposes.
  191.    param buf1 - First word.
  192.    param buf2 - Second word.
  193.    return  <0 - less, =0 - equal,  >0 - greater.
  194.    @ingroup bitfunc 
  195. */
  196. template<typename T> int wordcmp0(T w1, T w2)
  197. {
  198.     while (w1 != w2)
  199.     {
  200.         int res = (w1 & 1) - (w2 & 1);
  201.         if (res != 0) return res;
  202.         w1 >>= 1;
  203.         w2 >>= 1;
  204.     }
  205.     return 0;
  206. }
  207. /*! 
  208.    brief Lexicographical comparison of two words as bit strings.
  209.    Auxiliary implementation for testing and reference purposes.
  210.    param buf1 - First word.
  211.    param buf2 - Second word.
  212.    return  <0 - less, =0 - equal,  >0 - greater.
  213.    @ingroup bitfunc 
  214. */
  215. /*
  216. template<typename T> int wordcmp(T w1, T w2)
  217. {
  218.     T diff = w1 ^ w2;
  219.     return diff ? ((w1 & diff & (diff ^ (diff - 1)))? 1 : -1) : 0; 
  220. }
  221. */
  222. template<typename T> int wordcmp(T a, T b)
  223. {
  224.     T diff = a ^ b;
  225.     return diff? ( (a & diff & -diff)? 1 : -1 ) : 0;
  226. }
  227. // Low bit extraction
  228. // x & (x ^ (x-1))
  229. /**
  230.     Internal structure. Copyright information.
  231. */
  232. template<bool T> struct _copyright
  233. {
  234.     static const char _p[];
  235. };
  236. template<bool T> const char _copyright<T>::_p[] = 
  237.     "BitMagic Library. v.3.2.1 (c) 2002-2003 Anatoliy Kuznetsov.";
  238. /*! 
  239.    brief Byte orders recognized by the library.
  240. */
  241. enum ByteOrder
  242. {
  243. BigEndian    = 0,
  244. LittleEndian = 1
  245. };
  246. /**
  247.     Internal structure. Different global settings.
  248. */
  249. template<bool T> struct globals
  250. {
  251.     struct bo
  252.     {
  253.         ByteOrder  _byte_order;
  254.         bo()
  255.         {
  256.             unsigned x;
  257.         unsigned char *s = (unsigned char *)&x;
  258.             s[0] = 1;
  259.             s[1] = 2;
  260.             s[2] = 3;
  261.             s[3] = 4;
  262.             if(x == 0x04030201) 
  263.             {
  264.                 _byte_order = LittleEndian;
  265.                 return;
  266.             }
  267.             if(x == 0x01020304) 
  268.             {
  269.                 _byte_order = BigEndian;
  270.                 return;
  271.             }
  272.             BM_ASSERT(0); // "Invalid Byte Ordern"
  273.         _byte_order = LittleEndian;
  274.         }
  275.     };
  276.     static bo  _bo;
  277.     static ByteOrder byte_order() { return _bo._byte_order; }
  278. };
  279. template<bool T> typename globals<T>::bo globals<T>::_bo;
  280. /*
  281.    brief Binary search for the block where bit = pos located.
  282.    param buf - GAP buffer pointer.
  283.    param pos - index of the element.
  284.    param is_set - output. GAP value (0 or 1). 
  285.    return GAP index.
  286.    @ingroup gapfunc
  287. */
  288. template<typename T> 
  289. unsigned gap_bfind(const T* buf, unsigned pos, unsigned* is_set)
  290. {
  291.     BM_ASSERT(pos < bm::gap_max_bits);
  292. *is_set = (*buf) & 1;
  293. register unsigned start = 1;
  294. register unsigned end = 1 + ((*buf) >> 3);
  295. while ( start != end )
  296. {
  297. unsigned curr = (start + end) >> 1;
  298. if ( buf[curr] < pos )
  299. start = curr + 1;
  300. else
  301. end = curr;
  302. }
  303. *is_set ^= ((start-1) & 1);
  304. return start; 
  305. }
  306. /*!
  307.    brief Tests if bit = pos is true.
  308.    param buf - GAP buffer pointer.
  309.    param pos - index of the element.
  310.    return true if position is in "1" gap
  311.    @ingroup gapfunc
  312. */
  313. template<typename T> unsigned gap_test(const T* buf, unsigned pos)
  314. {
  315.     BM_ASSERT(pos < bm::gap_max_bits);
  316. unsigned start = 1;
  317.     unsigned end = 1 + ((*buf) >> 3);
  318.     if (end - start < 10)
  319.     {
  320.         unsigned sv = *buf & 1;
  321.         unsigned sv1= sv ^ 1;
  322.         if (buf[1] >= pos) return sv;
  323.         if (buf[2] >= pos) return sv1;
  324.         if (buf[3] >= pos) return sv;
  325.         if (buf[4] >= pos) return sv1;
  326.         if (buf[5] >= pos) return sv;
  327.         if (buf[6] >= pos) return sv1;
  328.         if (buf[7] >= pos) return sv;
  329.         if (buf[8] >= pos) return sv1;
  330.         if (buf[9] >= pos) return sv;
  331.         BM_ASSERT(0);
  332.     }
  333.     else
  334. while ( start != end )
  335. {
  336. unsigned curr = (start + end) >> 1;
  337. if ( buf[curr] < pos )
  338. start = curr + 1;
  339. else
  340. end = curr;
  341. }
  342. return ((*buf) & 1) ^ ((--start) & 1); 
  343. }
  344. /*! For each non-zero block executes supplied function.
  345. */
  346. template<class T, class F> 
  347. void for_each_nzblock(T*** root, unsigned size1, unsigned size2, F& f)
  348. {
  349.     unsigned block_idx = 0;
  350.     for (unsigned i = 0; i < size1; ++i)
  351.     {
  352.         T** blk_blk = root[i];
  353.         if (!blk_blk) 
  354.         {
  355.             block_idx += bm::set_array_size;
  356.             continue;
  357.         }
  358.         for (unsigned j = 0;j < size2; ++j, ++block_idx)
  359.         {
  360.             if (blk_blk[j]) f(blk_blk[j], block_idx);
  361.         }
  362.     }  
  363. }
  364. /*! For each non-zero block executes supplied function-predicate.
  365.     Function returns if function-predicate returns true
  366. */
  367. template<class T, class F> 
  368. bool for_each_nzblock_if(T*** root, unsigned size1, unsigned size2, F& f)
  369. {
  370.     unsigned block_idx = 0;
  371.     for (unsigned i = 0; i < size1; ++i)
  372.     {
  373.         T** blk_blk = root[i];
  374.         if (!blk_blk) 
  375.         {
  376.             block_idx += bm::set_array_size;
  377.             continue;
  378.         }
  379.         for (unsigned j = 0;j < size2; ++j, ++block_idx)
  380.         {
  381.             if (blk_blk[j]) 
  382.                 if (f(blk_blk[j], block_idx)) return true;
  383.         }
  384.     }
  385.     return false;
  386. }
  387. /*! For each block executes supplied function.
  388. */
  389. template<class T, class F> 
  390. void for_each_block(T*** root, unsigned size1, unsigned size2, F& f)
  391. {
  392.     unsigned block_idx = 0;
  393.     for (unsigned i = 0; i < size1; ++i)
  394.     {
  395.         T** blk_blk = root[i];
  396.         if (blk_blk)
  397.         {
  398.             for (unsigned j = 0;j < size2; ++j, ++block_idx)
  399.             {
  400.                 f(blk_blk[j], block_idx);
  401.             }
  402.         }
  403.         else
  404.         {
  405.             for (unsigned j = 0;j < size2; ++j, ++block_idx)
  406.             {
  407.                 f(0, block_idx);
  408.             }
  409.         }
  410.     }  
  411. }
  412. /*! Special BM optimized analog of STL for_each
  413. */
  414. template<class T, class F> F bmfor_each(T first, T last, F f)
  415. {
  416.     do
  417.     {
  418.         f(*first);
  419.         ++first;
  420.     } while (first < last);
  421.     return f;
  422. }
  423. /*! Computes SUM of all elements of the sequence
  424. */
  425. template<class T> T sum_arr(T* first, T* last)
  426. {
  427.     T sum = 0;
  428.     while (first < last)
  429.     {
  430.         sum += *first;
  431.         ++first;
  432.     }
  433.     return sum;
  434. }
  435. /*! 
  436.    brief Calculates number of bits ON in GAP buffer.
  437.    param buf - GAP buffer pointer.
  438.    return Number of non-zero bits.
  439.    @ingroup gapfunc
  440. */
  441. template<typename T> unsigned gap_bit_count(const T* buf) 
  442. {
  443.     register const T* pcurr = buf;
  444.     register const T* pend = pcurr + (*pcurr >> 3);
  445.     register unsigned bits_counter = 0;
  446.     ++pcurr;
  447.     if (*buf & 1)
  448.     {
  449.         bits_counter += *pcurr + 1;
  450.         ++pcurr;
  451.     }
  452.     ++pcurr;  // set GAP to 1
  453.     while (pcurr <= pend)
  454.     {
  455.         bits_counter += *pcurr - *(pcurr-1);
  456.         pcurr += 2; // jump to the next positive GAP
  457.     } 
  458.     return bits_counter;
  459. }
  460. /*!
  461.    brief Counts 1 bits in GAP buffer in the closed [left, right] diapason.
  462.    param buf - GAP buffer pointer.
  463.    param left - leftmost bit index to start from
  464.    param right- rightmost bit index
  465.    return Number of non-zero bits.
  466. */
  467. template<typename T>
  468. unsigned gap_bit_count_range(const T* buf, T left, T right)
  469. {
  470.     BM_ASSERT(left <= right);
  471.     
  472.     const T* pcurr = buf;
  473.     const T* pend = pcurr + (*pcurr >> 3);
  474.     
  475.     unsigned bits_counter = 0;
  476.     unsigned is_set;
  477.     unsigned start_pos = gap_bfind(buf, left, &is_set);
  478.     pcurr = buf + start_pos;
  479.     if (right <= *pcurr) // we are in the target block right now
  480.     {
  481.         if (is_set)
  482.             bits_counter = (right - left + 1);
  483.         return bits_counter;
  484.     }
  485.     if (is_set)
  486.         bits_counter += *pcurr - left + 1;
  487.     unsigned prev_gap = *pcurr++;
  488.     is_set ^= 1;
  489.     while (right > *pcurr)
  490.     {
  491.         if (is_set)
  492.             bits_counter += *pcurr - prev_gap;
  493.         if (pcurr == pend) 
  494.             return bits_counter;
  495.         prev_gap = *pcurr++;
  496.         is_set ^= 1;
  497.     }
  498.     if (is_set)
  499.         bits_counter += right - prev_gap;
  500.     return bits_counter;
  501. }
  502. /*! 
  503.    brief Lexicographical comparison of GAP buffers.
  504.    param buf1 - First GAP buffer pointer.
  505.    param buf2 - Second GAP buffer pointer.
  506.    return  <0 - less, =0 - equal,  >0 - greater.
  507.    @ingroup gapfunc
  508. */
  509. template<typename T> int gapcmp(const T* buf1, const T* buf2)
  510. {
  511.     const T* pcurr1 = buf1;
  512.     const T* pend1 = pcurr1 + (*pcurr1 >> 3);
  513.     unsigned bitval1 = *buf1 & 1;
  514.     ++pcurr1;
  515.     const T* pcurr2 = buf2;
  516.     unsigned bitval2 = *buf2 & 1;
  517.     ++pcurr2;
  518.     while (pcurr1 <= pend1)
  519.     {
  520.         if (*pcurr1 == *pcurr2)
  521.         {
  522.             if (bitval1 != bitval2)
  523.             {
  524.                 return (bitval1) ? 1 : -1;
  525.             }
  526.         }
  527.         else
  528.         {
  529.             if (bitval1 == bitval2)
  530.             {
  531.                 if (bitval1)
  532.                 {
  533.                     return (*pcurr1 < *pcurr2) ? -1 : 1;
  534.                 }
  535.                 else
  536.                 {
  537.                     return (*pcurr1 < *pcurr2) ? 1 : -1;
  538.                 }
  539.             }
  540.             else
  541.             {
  542.                 return (bitval1) ? 1 : -1;
  543.             }
  544.         }
  545.         ++pcurr1; ++pcurr2;
  546.         bitval1 ^= 1;
  547.         bitval2 ^= 1;
  548.     }
  549.     return 0;
  550. }
  551. /*!
  552.    brief Abstract operation for GAP buffers. 
  553.           Receives functor F as a template argument
  554.    param dest - destination memory buffer.
  555.    param vect1 - operand 1 GAP encoded buffer.
  556.    param vect1_mask - XOR mask for starting bitflag for vector1 
  557.    can be 0 or 1 (1 inverts the vector)
  558.    param vect2 - operand 2 GAP encoded buffer.
  559.    param vect2_mask - same as vect1_mask
  560.    param f - operation functor.
  561.    note Internal function.
  562.    @ingroup gapfunc
  563. */
  564. template<typename T, class F> 
  565. void gap_buff_op(T*         BMRESTRICT dest, 
  566.                  const T*   BMRESTRICT vect1,
  567.                  unsigned   vect1_mask, 
  568.                  const T*   BMRESTRICT vect2,
  569.                  unsigned   vect2_mask, 
  570.                  F f)
  571. {
  572.     register const T*  cur1 = vect1;
  573.     register const T*  cur2 = vect2;
  574.     unsigned bitval1 = (*cur1++ & 1) ^ vect1_mask;
  575.     unsigned bitval2 = (*cur2++ & 1) ^ vect2_mask;
  576.     
  577.     unsigned bitval = f(bitval1, bitval2);
  578.     unsigned bitval_prev = bitval;
  579.     register T* res = dest; 
  580.     *res = bitval;
  581.     ++res;
  582.     while (1)
  583.     {
  584.         bitval = f(bitval1, bitval2);
  585.         // Check if GAP value changes and we need to 
  586.         // start the next one.
  587.         if (bitval != bitval_prev)
  588.         {
  589.             ++res;
  590.             bitval_prev = bitval;
  591.         }
  592.         if (*cur1 < *cur2)
  593.         {
  594.             *res = *cur1;
  595.             ++cur1;
  596.             bitval1 ^= 1;
  597.         }
  598.         else // >=
  599.         {
  600.             *res = *cur2;
  601.             if (*cur2 < *cur1)
  602.             {
  603.                 bitval2 ^= 1;                
  604.             }
  605.             else  // equal
  606.             {
  607.                 if (*cur2 == (bm::gap_max_bits - 1))
  608.                 {
  609.                     break;
  610.                 }
  611.                 ++cur1;
  612.                 bitval1 ^= 1;
  613.                 bitval2 ^= 1;
  614.             }
  615.             ++cur2;
  616.         }
  617.     } // while
  618.     unsigned dlen = (unsigned)(res - dest);
  619.     *dest = (*dest & 7) + (dlen << 3);
  620. }
  621. /*!
  622.    brief Abstract distance(similarity) operation for GAP buffers. 
  623.           Receives functor F as a template argument
  624.    param vect1 - operand 1 GAP encoded buffer.
  625.    param vect2 - operand 2 GAP encoded buffer.
  626.    param f - operation functor.
  627.    note Internal function.
  628.    @ingroup gapfunc
  629. */
  630. /*
  631. template<typename T, class F> 
  632. unsigned gap_buff_count_op(const T*  vect1, const T*  vect2, F f)
  633. {
  634.     register const T* cur1 = vect1;
  635.     register const T* cur2 = vect2;
  636.     unsigned bitval1 = (*cur1++ & 1);
  637.     unsigned bitval2 = (*cur2++ & 1);
  638.     unsigned bitval = f(bitval1, bitval2);
  639.     unsigned bitval_prev = bitval;
  640.     unsigned count = 0;
  641.     T res;
  642.     T res_prev;
  643.     while (1)
  644.     {
  645.         bitval = f(bitval1, bitval2);
  646.         // Check if GAP value changes and we need to 
  647.         // start the next one.
  648.         if (bitval != bitval_prev)
  649.         {
  650.             bitval_prev = bitval;
  651.         }
  652.         if (*cur1 < *cur2)
  653.         {
  654.             if (bitval)
  655.                 count += *cur1; 
  656.             ++cur1;
  657.             bitval1 ^= 1;
  658.         }
  659.         else // >=
  660.         {
  661.             if (bitval)
  662.                 count += *cur2; 
  663.             if (*cur2 < *cur1)
  664.             {
  665.                 bitval2 ^= 1;                
  666.             }
  667.             else  // equal
  668.             {
  669.                 if (*cur2 == (bm::gap_max_bits - 1))
  670.                 {
  671.                     break;
  672.                 }
  673.                 ++cur1;
  674.                 bitval1 ^= 1;
  675.                 bitval2 ^= 1;
  676.             }
  677.             ++cur2;
  678.         }
  679.     } // while
  680.     return count;
  681. }
  682. */
  683. /*!
  684.    brief Sets or clears bit in the GAP buffer.
  685.    param val - new bit value
  686.    param buf - GAP buffer.
  687.    param pos - Index of bit to set.
  688.    param is_set - (OUT) flag if bit was actually set.
  689.    return New GAP buffer length. 
  690.    @ingroup gapfunc
  691. */
  692. template<typename T> unsigned gap_set_value(unsigned val, 
  693.                                             T* BMRESTRICT buf, 
  694.                                             unsigned pos, 
  695.                                             unsigned* BMRESTRICT is_set)
  696. {
  697.     BM_ASSERT(pos < bm::gap_max_bits);
  698.     unsigned curr = gap_bfind(buf, pos, is_set);
  699.     register T end = (*buf >> 3);
  700. if (*is_set == val)
  701. {
  702. *is_set = 0;
  703. return end;
  704. }
  705.     *is_set = 1;
  706.     register T* pcurr = buf + curr;
  707.     register T* pprev = pcurr - 1;
  708.     register T* pend = buf + end;
  709.     // Special case, first bit GAP operation. There is no platform beside it.
  710.     // initial flag must be inverted.
  711.     if (pos == 0)
  712.     {
  713.         *buf ^= 1;
  714.         if ( buf[1] ) // We need to insert a 1 bit platform here.
  715.         {
  716.             ::memmove(&buf[2], &buf[1], (end - 1) * sizeof(gap_word_t));
  717.             buf[1] = 0;
  718.             ++end;
  719.         }
  720.         else // Only 1 bit in the GAP. We need to delete the first GAP.
  721.         {
  722.             pprev = buf + 1;
  723.             pcurr = pprev + 1;
  724.             do
  725.             {
  726.                 *pprev++ = *pcurr++;
  727.             } while (pcurr < pend);
  728.             --end;
  729.         }
  730.     }
  731.     else if (curr > 1 && ((unsigned)(*pprev))+1 == pos) // Left border bit
  732. {
  733.      ++(*pprev);
  734.    if (*pprev == *pcurr)  // Curr. GAP to be merged with prev.GAP.
  735.    {
  736.             --end;
  737.             if (pcurr != pend) // GAP merge: 2 GAPS to be deleted 
  738.             {
  739.                 --end;
  740.                 ++pcurr;
  741.                 do
  742.                 {
  743.                     *pprev++ = *pcurr++;
  744.                 } while (pcurr < pend);
  745.             }
  746.    }    
  747.     }
  748. else if (*pcurr == pos) // Rightmost bit in the GAP. Border goes left.
  749. {
  750. --(*pcurr);       
  751. if (pcurr == pend)
  752.         {
  753.    ++end;
  754.         }
  755. }
  756. else  // Worst case we need to split current block.
  757. {
  758.         ::memmove(pcurr+2, pcurr,(end - curr + 1)*sizeof(T));
  759.         *pcurr++ = pos - 1;
  760.         *pcurr = pos;
  761. end+=2;
  762. }
  763.     // Set correct length word.
  764.     *buf = (*buf & 7) + (end << 3);
  765.     buf[end] = bm::gap_max_bits - 1;
  766.     return end;
  767. }
  768. //------------------------------------------------------------------------
  769. /**
  770.     brief Searches for the next 1 bit in the GAP block
  771.     param buf - GAP buffer
  772.     param nbit - bit index to start checking from.
  773.     param prev - returns previously checked value
  774.     @ingroup gapfunc
  775. */
  776. template<typename T> int gap_find_in_block(const T* buf, 
  777.                                            unsigned nbit, 
  778.                                            bm::id_t* prev)
  779. {
  780.     BM_ASSERT(nbit < bm::gap_max_bits);
  781.     unsigned bitval;
  782.     unsigned gap_idx = bm::gap_bfind(buf, nbit, &bitval);
  783.     if (bitval) // positive block.
  784.     {
  785.        return 1;
  786.     }
  787.     register unsigned val = buf[gap_idx] + 1;
  788.     *prev += val - nbit;
  789.  
  790.     return (val != bm::gap_max_bits);  // no bug here.
  791. }
  792. /*! 
  793.    brief Sets bits to 1 in the bitblock.
  794.    param dest - Bitset buffer.
  795.    param bitpos - Offset of the start bit.
  796.    param bitcount - number of bits to set.
  797.    @ingroup bitfunc
  798. */  
  799. inline void or_bit_block(unsigned* dest, 
  800.                          unsigned bitpos, 
  801.                          unsigned bitcount)
  802. {
  803.     unsigned nbit  = unsigned(bitpos & bm::set_block_mask); 
  804.     unsigned nword = unsigned(nbit >> bm::set_word_shift); 
  805.     nbit &= bm::set_word_mask;
  806.     bm::word_t* word = dest + nword;
  807.     if (bitcount == 1)  // special case (only 1 bit to set)
  808.     {
  809.         *word |= unsigned(1 << nbit);
  810.         return;
  811.     }
  812.     if (nbit) // starting position is not aligned
  813.     {
  814.         unsigned right_margin = nbit + bitcount;
  815.         // here we checking if we setting bits only in the current
  816.         // word. Example: 00111000000000000000000000000000 (32 bits word)
  817.         if (right_margin < 32) 
  818.         {
  819.             unsigned mask = 
  820.                 block_set_table<true>::_right[nbit] & 
  821.                 block_set_table<true>::_left[right_margin-1];
  822.             *word |= mask;
  823.             return; // we are done
  824.         }
  825.         else
  826.         {
  827.             *word |= block_set_table<true>::_right[nbit];
  828.             bitcount -= 32 - nbit;
  829.         }
  830.         ++word;
  831.     }
  832.     // now we are word aligned, lets find out how many words we 
  833.     // can now turn ON using loop
  834.     for ( ;bitcount >= 32; bitcount -= 32) 
  835.     {
  836.         *word++ = 0xffffffff;
  837.     }
  838.     if (bitcount) 
  839.     {
  840.         *word |= block_set_table<true>::_left[bitcount-1];
  841.     }
  842. }
  843. /*! 
  844.    brief SUB (AND NOT) bit interval to 1 in the bitblock.
  845.    param dest - Bitset buffer.
  846.    param bitpos - Offset of the start bit.
  847.    param bitcount - number of bits to set.
  848.    @ingroup bitfunc
  849. */  
  850. inline void sub_bit_block(unsigned* dest, 
  851.                           unsigned bitpos, 
  852.                           unsigned bitcount)
  853. {
  854.     unsigned nbit  = unsigned(bitpos & bm::set_block_mask); 
  855.     unsigned nword = unsigned(nbit >> bm::set_word_shift); 
  856.     nbit &= bm::set_word_mask;
  857.     bm::word_t* word = dest + nword;
  858.     if (bitcount == 1)  // special case (only 1 bit to set)
  859.     {
  860.         *word &= ~unsigned(1 << nbit);
  861.         return;
  862.     }
  863.     if (nbit) // starting position is not aligned
  864.     {
  865.         unsigned right_margin = nbit + bitcount;
  866.         // here we checking if we setting bits only in the current
  867.         // word. Example: 00111000000000000000000000000000 (32 bits word)
  868.         if (right_margin < 32) 
  869.         {
  870.             unsigned mask = 
  871.                 block_set_table<true>::_right[nbit] & 
  872.                 block_set_table<true>::_left[right_margin-1];
  873.             *word &= ~mask;
  874.             return; // we are done
  875.         }
  876.         else
  877.         {
  878.             *word &= ~block_set_table<true>::_right[nbit];
  879.             bitcount -= 32 - nbit;
  880.         }
  881.         ++word;
  882.     }
  883.     // now we are word aligned, lets find out how many words we 
  884.     // can now turn ON using loop
  885.     for ( ;bitcount >= 32; bitcount -= 32) 
  886.     {
  887.         *word++ = 0;
  888.     }
  889.     if (bitcount) 
  890.     {
  891.         *word &= ~block_set_table<true>::_left[bitcount-1];
  892.     }
  893. }
  894. /*! 
  895.    brief XOR bit interval to 1 in the bitblock.
  896.    param dest - Bitset buffer.
  897.    param bitpos - Offset of the start bit.
  898.    param bitcount - number of bits to set.
  899.    @ingroup bitfunc
  900. */  
  901. inline void xor_bit_block(unsigned* dest, 
  902.                           unsigned bitpos, 
  903.                           unsigned bitcount)
  904. {
  905.     unsigned nbit  = unsigned(bitpos & bm::set_block_mask); 
  906.     unsigned nword = unsigned(nbit >> bm::set_word_shift); 
  907.     nbit &= bm::set_word_mask;
  908.     bm::word_t* word = dest + nword;
  909.     if (bitcount == 1)  // special case (only 1 bit to set)
  910.     {
  911.         *word ^= unsigned(1 << nbit);
  912.         return;
  913.     }
  914.     if (nbit) // starting position is not aligned
  915.     {
  916.         unsigned right_margin = nbit + bitcount;
  917.         // here we checking if we setting bits only in the current
  918.         // word. Example: 00111000000000000000000000000000 (32 bits word)
  919.         if (right_margin < 32) 
  920.         {
  921.             unsigned mask = 
  922.                 block_set_table<true>::_right[nbit] & 
  923.                 block_set_table<true>::_left[right_margin-1];
  924.             *word ^= mask;
  925.             return; // we are done
  926.         }
  927.         else
  928.         {
  929.             *word ^= block_set_table<true>::_right[nbit];
  930.             bitcount -= 32 - nbit;
  931.         }
  932.         ++word;
  933.     }
  934.     // now we are word aligned, lets find out how many words we 
  935.     // can now turn ON using loop
  936.     for ( ;bitcount >= 32; bitcount -= 32) 
  937.     {
  938.         *word++ ^= 0xffffffff;
  939.     }
  940.     if (bitcount) 
  941.     {
  942.         *word ^= block_set_table<true>::_left[bitcount-1];
  943.     }
  944. }
  945. /*!
  946.    brief SUB (AND NOT) GAP block to bitblock.
  947.    param dest - bitblock buffer pointer.
  948.    param buf  - GAP buffer pointer.
  949.    @ingroup gapfunc
  950. */
  951. template<typename T> 
  952. void gap_sub_to_bitset(unsigned* dest, const T*  buf)
  953. {
  954.     register const T* pcurr = buf;    
  955.     register const T* pend = pcurr + (*pcurr >> 3);
  956.     ++pcurr;
  957.     if (*buf & 1)  // Starts with 1
  958.     {
  959.         sub_bit_block(dest, 0, *pcurr + 1);
  960.         ++pcurr;
  961.     }
  962.     ++pcurr; // now we are in GAP "1" again
  963.     while (pcurr <= pend)
  964.     {
  965.         unsigned bitpos = *(pcurr-1) + 1;
  966.         BM_ASSERT(*pcurr > *(pcurr-1));
  967.         unsigned gap_len = *pcurr - *(pcurr-1);
  968.         sub_bit_block(dest, bitpos, gap_len);
  969.         pcurr += 2;
  970.     }
  971. }
  972. /*!
  973.    brief XOR GAP block to bitblock.
  974.    param dest - bitblock buffer pointer.
  975.    param buf  - GAP buffer pointer.
  976.    @ingroup gapfunc
  977. */
  978. template<typename T> 
  979. void gap_xor_to_bitset(unsigned* dest, const T*  buf)
  980. {
  981.     register const T* pcurr = buf;    
  982.     register const T* pend = pcurr + (*pcurr >> 3);
  983.     ++pcurr;
  984.     if (*buf & 1)  // Starts with 1
  985.     {
  986.         xor_bit_block(dest, 0, *pcurr + 1);
  987.         ++pcurr;
  988.     }
  989.     ++pcurr; // now we are in GAP "1" again
  990.     while (pcurr <= pend)
  991.     {
  992.         unsigned bitpos = *(pcurr-1) + 1;
  993.         BM_ASSERT(*pcurr > *(pcurr-1));
  994.         unsigned gap_len = *pcurr - *(pcurr-1);
  995.         xor_bit_block(dest, bitpos, gap_len);
  996.         pcurr += 2;
  997.     }
  998. }
  999. /*!
  1000.    brief Adds(OR) GAP block to bitblock.
  1001.    param dest - bitblock buffer pointer.
  1002.    param buf  - GAP buffer pointer.
  1003.    @ingroup gapfunc
  1004. */
  1005. template<typename T> 
  1006. void gap_add_to_bitset(unsigned* dest, const T*  buf)
  1007. {
  1008.     register const T* pcurr = buf;    
  1009.     register const T* pend = pcurr + (*pcurr >> 3);
  1010.     ++pcurr;
  1011.     if (*buf & 1)  // Starts with 1
  1012.     {
  1013.         or_bit_block(dest, 0, *pcurr + 1);
  1014.         ++pcurr;
  1015.     }
  1016.     ++pcurr; // now we are in GAP "1" again
  1017.     while (pcurr <= pend)
  1018.     {
  1019.         unsigned bitpos = *(pcurr-1) + 1;
  1020.         BM_ASSERT(*pcurr > *(pcurr-1));
  1021.         unsigned gap_len = *pcurr - *(pcurr-1);
  1022.         or_bit_block(dest, bitpos, gap_len);
  1023.         pcurr += 2;
  1024.     }
  1025. }
  1026. /*!
  1027.    brief ANDs GAP block to bitblock.
  1028.    param dest - bitblock buffer pointer.
  1029.    param buf  - GAP buffer pointer.
  1030.    @ingroup gapfunc
  1031. */
  1032. template<typename T> 
  1033. void gap_and_to_bitset(unsigned* dest, const T*  buf)
  1034. {
  1035.     register const T* pcurr = buf;    
  1036.     register const T* pend = pcurr + (*pcurr >> 3);
  1037.     ++pcurr;
  1038.     if (! (*buf & 1) )  // Starts with 0 
  1039.     {
  1040.         // Instead of AND we can SUB 0 gaps here 
  1041.         sub_bit_block(dest, 0, *pcurr + 1);
  1042.         ++pcurr;
  1043.     }
  1044.     ++pcurr; // now we are in GAP "0" again
  1045.     while (pcurr <= pend)
  1046.     {
  1047.         unsigned bitpos = *(pcurr-1) + 1;
  1048.         BM_ASSERT(*pcurr > *(pcurr-1));
  1049.         unsigned gap_len = *pcurr - *(pcurr-1);
  1050.         sub_bit_block(dest, bitpos, gap_len);
  1051.         pcurr += 2;
  1052.     }
  1053. }
  1054. /*!
  1055.    brief Compute bitcount of bit block AND masked by GAP block.
  1056.    param dest - bitblock buffer pointer.
  1057.    param buf  - GAP buffer pointer.
  1058.    @ingroup gapfunc bitfunc
  1059. */
  1060. template<typename T> 
  1061. bm::id_t gap_bitset_and_count(const unsigned* block, const T*  buf)
  1062. {
  1063.     BM_ASSERT(block);
  1064.     register const T* pcurr = buf;    
  1065.     register const T* pend = pcurr + (*pcurr >> 3);
  1066.     ++pcurr;
  1067.     bm::id_t count = 0;
  1068.     if (*buf & 1)  // Starts with 1
  1069.     {
  1070.         count += bit_block_calc_count_range(block, 0, *pcurr);
  1071.         ++pcurr;
  1072.     }
  1073.     ++pcurr; // now we are in GAP "1" again
  1074.     while (pcurr <= pend)
  1075.     {
  1076.         bm::id_t c = bit_block_calc_count_range(block, *(pcurr-1)+1, *pcurr);
  1077.         count += c;
  1078.         pcurr += 2;
  1079.     }
  1080.     return count;
  1081. }
  1082. /*!
  1083.    brief Compute bitcount of bit block SUB masked by GAP block.
  1084.    param dest - bitblock buffer pointer.
  1085.    param buf  - GAP buffer pointer.
  1086.    @ingroup gapfunc bitfunc
  1087. */
  1088. template<typename T> 
  1089. bm::id_t gap_bitset_sub_count(const unsigned* block, const T*  buf)
  1090. {
  1091.     BM_ASSERT(block);
  1092.     register const T* pcurr = buf;    
  1093.     register const T* pend = pcurr + (*pcurr >> 3);
  1094.     ++pcurr;
  1095.     bm::id_t count = 0;
  1096.     if (!(*buf & 1))  // Starts with 0
  1097.     {
  1098.         count += bit_block_calc_count_range(block, 0, *pcurr);
  1099.         ++pcurr;
  1100.     }
  1101.     ++pcurr; // now we are in GAP "0" again
  1102.     for (;pcurr <= pend; pcurr+=2)
  1103.     {
  1104.         count += bit_block_calc_count_range(block, *(pcurr-1)+1, *pcurr);
  1105.     }
  1106.     return count;
  1107. }
  1108. /*!
  1109.    brief Compute bitcount of bit block XOR masked by GAP block.
  1110.    param dest - bitblock buffer pointer.
  1111.    param buf  - GAP buffer pointer.
  1112.    @ingroup gapfunc bitfunc
  1113. */
  1114. template<typename T> 
  1115. bm::id_t gap_bitset_xor_count(const unsigned* block, const T*  buf)
  1116. {
  1117.     BM_ASSERT(block);
  1118.     register const T* pcurr = buf;    
  1119.     register const T* pend = pcurr + (*pcurr >> 3);
  1120.     ++pcurr;
  1121.     unsigned bitval = *buf & 1;
  1122.     
  1123.     register bm::id_t count = bit_block_calc_count_range(block, 0, *pcurr);
  1124.     if (bitval)
  1125.     {
  1126.         count = *pcurr + 1 - count;
  1127.     }
  1128.     
  1129.     for (bitval^=1, ++pcurr; pcurr <= pend; bitval^=1, ++pcurr)
  1130.     {
  1131.         T prev = *(pcurr-1)+1;
  1132.         bm::id_t c = bit_block_calc_count_range(block, prev, *pcurr);
  1133.         
  1134.         if (bitval) // 1 gap; means Result = Total_Bits - BitCount;
  1135.         {
  1136.             c = (*pcurr - prev + 1) - c;
  1137.         }
  1138.         
  1139.         count += c;
  1140.     }
  1141.     return count;
  1142. }
  1143. /*!
  1144.    brief Compute bitcount of bit block OR masked by GAP block.
  1145.    param dest - bitblock buffer pointer.
  1146.    param buf  - GAP buffer pointer.
  1147.    @ingroup gapfunc bitfunc
  1148. */
  1149. template<typename T> 
  1150. bm::id_t gap_bitset_or_count(const unsigned* block, const T*  buf)
  1151. {
  1152.     BM_ASSERT(block);
  1153.     register const T* pcurr = buf;    
  1154.     register const T* pend = pcurr + (*pcurr >> 3);
  1155.     ++pcurr;
  1156.     unsigned bitval = *buf & 1;
  1157.     
  1158.     register bm::id_t count;
  1159.     if (bitval)
  1160.     {
  1161.         count = *pcurr + 1;
  1162.     } 
  1163.     else
  1164.     {
  1165.         count = bit_block_calc_count_range(block, 0, *pcurr);
  1166.     }
  1167.     
  1168.     for (bitval^=1, ++pcurr; pcurr <= pend; bitval^=1, ++pcurr)
  1169.     {
  1170.         T prev = *(pcurr-1)+1;
  1171.         bm::id_t c;
  1172.         
  1173.         if (bitval)
  1174.         {
  1175.             c = (*pcurr - prev + 1);
  1176.         }
  1177.         else
  1178.         {
  1179.             c = bit_block_calc_count_range(block, prev, *pcurr);
  1180.         }
  1181.         
  1182.         count += c;
  1183.     }
  1184.     return count;
  1185. }
  1186. /*!
  1187.    brief Bitblock memset operation. 
  1188.    param dst - destination block.
  1189.    param value - value to set.
  1190.    @ingroup bitfunc
  1191. */
  1192. inline 
  1193. void bit_block_set(bm::word_t* BMRESTRICT dst, bm::word_t value)
  1194. {
  1195. //#ifdef BMVECTOPT
  1196. //    VECT_SET_BLOCK(dst, dst + bm::set_block_size, value);
  1197. //#else
  1198.     ::memset(dst, value, bm::set_block_size * sizeof(bm::word_t));
  1199. //#endif
  1200. }
  1201. /*!
  1202.    brief GAP block to bitblock conversion.
  1203.    param dest - bitblock buffer pointer.
  1204.    param buf  - GAP buffer pointer.
  1205.    param dest_size - length of the destination buffer.
  1206.    @ingroup gapfunc
  1207. */
  1208. template<typename T> 
  1209. void gap_convert_to_bitset(unsigned* dest, const T*  buf,  unsigned)
  1210. {
  1211.     bit_block_set(dest, 0);
  1212. // ::memset(dest, 0, dest_len * sizeof(unsigned));
  1213.     gap_add_to_bitset(dest, buf);
  1214. }
  1215. /*!
  1216.    brief Smart GAP block to bitblock conversion.
  1217.     Checks if GAP block is ALL-ZERO or ALL-ON. In those cases returns 
  1218.     pointer on special static bitblocks.
  1219.    param dest - bitblock buffer pointer.
  1220.    param buf  - GAP buffer pointer.
  1221.    param dest_size - length of the destination buffer.
  1222.    param set_max - max possible bitset length
  1223.    @ingroup gapfunc
  1224. */
  1225. template<typename T> 
  1226.         unsigned* gap_convert_to_bitset_smart(unsigned* dest,
  1227.                                               const T* buf, 
  1228.                                               unsigned dest_size,
  1229.                                               id_t set_max)
  1230. {
  1231.     if (buf[1] == set_max - 1)
  1232.     {
  1233.         return (buf[0] & 1) ? FULL_BLOCK_ADDR : 0;
  1234.     }
  1235.     gap_convert_to_bitset(dest, buf, dest_size);
  1236.     return dest;
  1237. }
  1238. /*!
  1239.    brief Calculates sum of all words in GAP block. (For debugging purposes)
  1240.    note For debugging and testing ONLY.
  1241.    param buf - GAP buffer pointer.
  1242.    return Sum of all words.
  1243.    @ingroup gapfunc
  1244. */
  1245. template<typename T> unsigned gap_control_sum(const T* buf)
  1246. {
  1247.     unsigned end = *buf >> 3;
  1248.     register const T* pcurr = buf;    
  1249.     register const T* pend = pcurr + (*pcurr >> 3);
  1250.     ++pcurr;
  1251.     if (*buf & 1)  // Starts with 1
  1252.     {
  1253.         ++pcurr;
  1254.     }
  1255.     ++pcurr; // now we are in GAP "1" again
  1256.     while (pcurr <= pend)
  1257.     {
  1258.         BM_ASSERT(*pcurr > *(pcurr-1));
  1259.         pcurr += 2;
  1260.     }
  1261.     return buf[end];
  1262. }
  1263. /*! 
  1264.    brief Sets all bits to 0 or 1 (GAP)
  1265.    param buf - GAP buffer pointer.
  1266.    param set_max - max possible bitset length
  1267.    @ingroup gapfunc
  1268. */
  1269. template<class T> void gap_set_all(T* buf, 
  1270.                                         unsigned set_max,
  1271.                                         unsigned value)
  1272. {
  1273.     BM_ASSERT(value == 0 || value == 1);
  1274.     *buf = (*buf & 6u) + (1u << 3) + value;
  1275.     *(++buf) = set_max - 1;
  1276. }
  1277. /*!
  1278.     brief Init gap block so it has block in it (can be whole block)
  1279.     param buf  - GAP buffer pointer.
  1280.     param from - one block start
  1281.     param to   - one block end
  1282.     param value - (block value)1 or 0
  1283.     param set_max - max possible bitset length
  1284.     
  1285.    @ingroup gapfunc
  1286. */
  1287. template<class T> 
  1288. void gap_init_range_block(T*       buf,
  1289.                           unsigned from,
  1290.                           unsigned to,
  1291.                           unsigned value,
  1292.                           unsigned set_max)
  1293. {
  1294.     BM_ASSERT(value == 0 || value == 1);
  1295.     unsigned gap_len;
  1296.     if (from == 0)
  1297.     {
  1298.         if (to == set_max - 1)
  1299.         {
  1300.             gap_set_all(buf, set_max, value);
  1301.         }
  1302.         else
  1303.         {
  1304.             gap_len = 2;
  1305.             buf[1] = to;
  1306.             buf[2] = set_max - 1;
  1307.             buf[0] =  (*buf & 6u) + (gap_len << 3) + value;
  1308.         }
  1309.         return;
  1310.     }
  1311.     // from != 0
  1312.     value = !value;
  1313.     if (to == set_max - 1)
  1314.     {
  1315.         gap_len = 2;
  1316.         buf[1] = from - 1;
  1317.         buf[2] = set_max - 1;
  1318.     }
  1319.     else
  1320.     {
  1321.         gap_len = 3;
  1322.         buf[1] = from - 1;
  1323.         buf[2] = to;
  1324.         buf[3] = set_max - 1;
  1325.     }
  1326.     buf[0] =  (*buf & 6u) + (gap_len << 3) + value;
  1327. }
  1328. /*! 
  1329.    brief Inverts all bits in the GAP buffer.
  1330.    param buf - GAP buffer pointer.
  1331.    @ingroup gapfunc
  1332. */
  1333. template<typename T> void gap_invert(T* buf)
  1334.     *buf ^= 1;
  1335. }
  1336. /*! 
  1337.    brief Temporary inverts all bits in the GAP buffer.
  1338.    
  1339.    In this function const-ness of the buffer means nothing.
  1340.    Calling this function again restores the status of the buffer.
  1341.    param buf - GAP buffer pointer. (Buffer IS changed) 
  1342.    @ingroup gapfunc
  1343. */
  1344. /*
  1345. template<typename T> void gap_temp_invert(const T* buf)
  1346. {
  1347.     T* buftmp = const_cast<T*>(buf);
  1348.     *buftmp ^= 1;
  1349. }
  1350. */
  1351. /*!
  1352.    brief Checks if GAP block is all-zero.
  1353.    param buf - GAP buffer pointer.
  1354.    param set_max - max possible bitset length
  1355.    returns true if all-zero.
  1356.    @ingroup gapfunc
  1357. */
  1358. template<typename T> 
  1359.              bool gap_is_all_zero(const T* buf, unsigned set_max)
  1360. {
  1361.     return (((*buf & 1)==0)  && (*(++buf) == set_max - 1));
  1362. }
  1363. /*!
  1364.    brief Checks if GAP block is all-one.
  1365.    param buf - GAP buffer pointer.
  1366.    param set_max - max possible bitset length
  1367.    returns true if all-one.
  1368.    @ingroup gapfunc
  1369. */
  1370. template<typename T> 
  1371.          bool gap_is_all_one(const T* buf, unsigned set_max)
  1372. {
  1373.     return ((*buf & 1)  && (*(++buf) == set_max - 1));
  1374. }
  1375. /*!
  1376.    brief Returs GAP block length.
  1377.    param buf - GAP buffer pointer.
  1378.    returns GAP block length.
  1379.    @ingroup gapfunc
  1380. */
  1381. template<typename T> unsigned gap_length(const T* buf)
  1382. {
  1383.     return (*buf >> 3) + 1;
  1384. }
  1385. /*!
  1386.    brief Returs GAP block capacity.
  1387.    param buf - GAP buffer pointer.
  1388.    returns GAP block capacity.
  1389.    @ingroup gapfunc
  1390. */
  1391. template<typename T> 
  1392. unsigned gap_capacity(const T* buf, const T* glevel_len)
  1393. {
  1394.     return glevel_len[(*buf >> 1) & 3];
  1395. }
  1396. /*!
  1397.    brief Returs GAP block capacity limit.
  1398.    param buf - GAP buffer pointer.
  1399.    param glevel_len - GAP lengths table (gap_len_table)
  1400.    returns GAP block limit.
  1401.    @ingroup gapfunc
  1402. */
  1403. template<typename T> 
  1404. unsigned gap_limit(const T* buf, const T* glevel_len)
  1405. {
  1406.     return glevel_len[(*buf >> 1) & 3]-4;
  1407. }
  1408. /*!
  1409.    brief Returs GAP blocks capacity level.
  1410.    param buf - GAP buffer pointer.
  1411.    returns GAP block capacity level.
  1412.    @ingroup gapfunc
  1413. */
  1414. template<typename T> unsigned gap_level(const T* buf)
  1415. {
  1416.     return (*buf >> 1) & 3;
  1417. }
  1418. /*!
  1419.    brief Sets GAP block capacity level.
  1420.    param buf - GAP buffer pointer.
  1421.    param level new GAP block capacity level.
  1422.    @ingroup gapfunc
  1423. */
  1424. template<typename T> void set_gap_level(T* buf, 
  1425.                                         unsigned level)
  1426. {
  1427.     BM_ASSERT(level < bm::gap_levels);
  1428.     *buf = ((level & 3) << 1) | (*buf & 1) | (*buf & ~7); 
  1429. }
  1430. /*!
  1431.    brief Calculates GAP block capacity level.
  1432.    param len - GAP buffer length.
  1433.    param glevel_len - GAP lengths table
  1434.    return GAP block capacity level. 
  1435.             -1 if block does not fit any level.
  1436.    @ingroup gapfunc
  1437. */
  1438. template<typename T>
  1439. inline int gap_calc_level(int len, const T* glevel_len)
  1440. {
  1441.     if (len <= (glevel_len[0]-4)) return 0;
  1442.     if (len <= (glevel_len[1]-4)) return 1;
  1443.     if (len <= (glevel_len[2]-4)) return 2;
  1444.     if (len <= (glevel_len[3]-4)) return 3;
  1445.     BM_ASSERT(bm::gap_levels == 4);
  1446.     return -1;
  1447. }
  1448. /*! @brief Returns number of free elements in GAP block array. 
  1449.     Difference between GAP block capacity on this level and actual GAP length.
  1450.     
  1451.     @param buf - GAP buffer pointer
  1452.     @parma glevel_len - GAP lengths table
  1453.     
  1454.     @return Number of free GAP elements
  1455.     @ingroup gapfunc
  1456. */
  1457. template<typename T>
  1458. inline unsigned gap_free_elements(const T* buf, const T* glevel_len)
  1459. {
  1460.     unsigned len = gap_length(buf);
  1461.     unsigned capacity = gap_capacity(buf, glevel_len);
  1462.     return capacity - len;
  1463. }
  1464. /*! 
  1465.    brief Lexicographical comparison of BIT buffers.
  1466.    param buf1 - First buffer pointer.
  1467.    param buf2 - Second buffer pointer.
  1468.    param len - Buffer length in elements (T).
  1469.    return  <0 - less, =0 - equal,  >0 - greater.
  1470.    @ingroup bitfunc 
  1471. */
  1472. template<typename T> 
  1473. int bitcmp(const T* buf1, const T* buf2, unsigned len)
  1474. {
  1475.     BM_ASSERT(len);
  1476.     const T* pend1 = buf1 + len; 
  1477.     do
  1478.     {
  1479.         T w1 = *buf1++;
  1480.         T w2 = *buf2++;
  1481.         T diff = w1 ^ w2;
  1482.     
  1483.         if (diff)
  1484.         { 
  1485.             return (w1 & diff & -diff) ? 1 : -1;
  1486.         }
  1487.     } while (buf1 < pend1);
  1488.     return 0;
  1489. }
  1490. /*! 
  1491.    brief Converts bit block to GAP. 
  1492.    param dest - Destinatio GAP buffer.
  1493.    param src - Source bitblock buffer.
  1494.    param bits - Number of bits to convert.
  1495.    param dest_len - length of the dest. buffer.
  1496.    return  New ength of GAP block or 0 if conversion failed 
  1497.    (insufficicent space).
  1498.    @ingroup gapfunc
  1499. */
  1500. template<typename T> 
  1501.     unsigned bit_convert_to_gap(T* BMRESTRICT dest, 
  1502.                                 const unsigned* BMRESTRICT src, 
  1503.                                 bm::id_t bits, 
  1504.                                 unsigned dest_len)
  1505. {
  1506.     register T* BMRESTRICT pcurr = dest;
  1507.     T* BMRESTRICT end = dest + dest_len; 
  1508.     register int bitval = (*src) & 1;
  1509.     *pcurr |= bitval;
  1510.     ++pcurr;
  1511.     *pcurr = 0;
  1512.     register unsigned bit_idx = 0;
  1513.     register int bitval_next;
  1514.     unsigned val = *src;
  1515.     do
  1516.     {
  1517.         // We can fast pace if *src == 0 or *src = 0xffffffff
  1518.         while (val == 0 || val == 0xffffffff)
  1519.         {
  1520.            bitval_next = val ? 1 : 0;
  1521.            if (bitval != bitval_next)
  1522.            {
  1523.                *pcurr++ = bit_idx-1; 
  1524.                BM_ASSERT((pcurr-1) == (dest+1) || *(pcurr-1) > *(pcurr-2));
  1525.                if (pcurr >= end)
  1526.                {
  1527.                    return 0; // OUT of memory
  1528.                }
  1529.                bitval = bitval_next;
  1530.            }
  1531.            bit_idx += sizeof(*src) * 8;
  1532.            if (bit_idx >= bits)
  1533.            {
  1534.                goto complete;
  1535.            }
  1536.            ++src;
  1537.            val = *src;
  1538.         }
  1539.         register unsigned mask = 1;
  1540.         while (mask)
  1541.         {
  1542.             // Now plain bitshifting. Optimization wanted.
  1543.             bitval_next = val & mask ? 1 : 0;
  1544.             if (bitval != bitval_next)
  1545.             {
  1546.                 *pcurr++ = bit_idx-1;
  1547.                 BM_ASSERT((pcurr-1) == (dest+1) || *(pcurr-1) > *(pcurr-2));
  1548.                 bitval = bitval_next;
  1549.                 if (pcurr >= end)
  1550.                 {
  1551.                     return 0; // OUT of memory
  1552.                 }
  1553.             }
  1554.             mask <<= 1;
  1555.             ++bit_idx;
  1556.         } // while mask
  1557.         if (bit_idx >= bits)
  1558.         {
  1559.             goto complete;
  1560.         }
  1561.         ++src;
  1562.         val = *src;
  1563.     } while(1);
  1564. complete:
  1565.     *pcurr = bit_idx-1;
  1566.     unsigned len = (unsigned)(pcurr - dest);
  1567.     *dest = (*dest & 7) + (len << 3);
  1568.     return len;
  1569. }
  1570. /*!
  1571.     @ingroup bitfunc 
  1572. */
  1573. template<typename T> T bit_convert_to_arr(T* BMRESTRICT dest, 
  1574.                                           const unsigned* BMRESTRICT src, 
  1575.                                           bm::id_t bits, 
  1576.                                           unsigned dest_len)
  1577. {
  1578.     register T* BMRESTRICT pcurr = dest;
  1579.     T* BMRESTRICT end = dest + dest_len; 
  1580.     register unsigned bit_idx = 0;
  1581.     do
  1582.     {
  1583.         register unsigned val = *src;
  1584.         // We can skip if *src == 0 
  1585.         while (val == 0)
  1586.         {
  1587.             bit_idx += sizeof(*src) * 8;
  1588.             if (bit_idx >= bits)
  1589.             {
  1590.                return (T)(pcurr - dest);
  1591.             }
  1592.             val = *(++src);
  1593.         }
  1594.         if (pcurr + sizeof(val)*8 > end) // insufficient space
  1595.         {
  1596.             return 0;
  1597.         }
  1598.         for (int i = 0; i < 32; i+=4)
  1599.         {
  1600.             if (val & 1)
  1601.                 *pcurr++ = bit_idx;
  1602.             val >>= 1; ++bit_idx;
  1603.             if (val & 1)
  1604.                 *pcurr++ = bit_idx;
  1605.             val >>= 1; ++bit_idx;
  1606.             if (val & 1)
  1607.                 *pcurr++ = bit_idx;
  1608.             val >>= 1; ++bit_idx;
  1609.             if (val & 1)
  1610.                 *pcurr++ = bit_idx;
  1611.             val >>= 1; ++bit_idx;
  1612.         }
  1613.         if (bits <= bit_idx)
  1614.             break;
  1615.         val = *(++src);
  1616.     } while (1);
  1617.     return (T)(pcurr - dest);
  1618. }
  1619. /*! 
  1620.     @brief Bitcount for bit string
  1621.     
  1622. Function calculates number of 1 bits in the given array of words.
  1623.     Make sure the addresses are aligned.
  1624.     @ingroup bitfunc 
  1625. */
  1626. inline 
  1627. bm::id_t bit_block_calc_count(const bm::word_t* block, 
  1628.   const bm::word_t* block_end)
  1629. {
  1630.     BM_ASSERT(block < block_end);
  1631. bm::id_t count = 0;
  1632. #ifdef BM64OPT
  1633.     // 64-bit optimized algorithm.
  1634.     const bm::id64_t* b1 = (bm::id64_t*) block;
  1635.     const bm::id64_t* b2 = (bm::id64_t*) block_end;
  1636.     bm::id64_t  acc = *b1++;  // accumulator (sparse vectors optimization)
  1637.     do
  1638.     {
  1639.         bm::id64_t in = *b1++;
  1640.         bm::id64_t acc_prev = acc;
  1641.         acc |= in;
  1642.         if (acc_prev &= in)  // counting bits in accumulator
  1643.         {
  1644.             acc = (acc & 0x5555555555555555LU) + (acc >> 1 & 0x5555555555555555LU);
  1645.             acc = (acc & 0x3333333333333333LU) + (acc >> 2 & 0x3333333333333333LU);
  1646.             acc = acc + (acc >> 4) & 0x0F0F0F0F0F0F0F0FLU;
  1647.             acc = acc + (acc >> 8);
  1648.             acc = acc + (acc >> 16);
  1649.             acc = acc + (acc >> 32) & 0x0000007F;
  1650.             count += (unsigned)acc;
  1651.             acc = acc_prev;
  1652.         }
  1653.     } while (b1 < b2);
  1654.     count += word_bitcount64(acc);  // count-in remaining accumulator 
  1655. #else
  1656.     // For 32 bit code the fastest method is
  1657.     // to use bitcount table for each byte in the block.
  1658.     // As optimization for sparse bitsets used bits accumulator
  1659.     // to collect ON bits using bitwise OR. 
  1660.     bm::word_t  acc = *block++;
  1661.     do
  1662.     {
  1663.         bm::word_t in = *block++;
  1664.         bm::word_t acc_prev = acc;
  1665.         acc |= in;
  1666.         if (acc_prev &= in)  // accumulator miss: counting bits
  1667.         {
  1668.             BM_INCWORD_BITCOUNT(count, acc);
  1669.             acc = acc_prev;
  1670.         }
  1671.     } while (block < block_end);
  1672.     BM_INCWORD_BITCOUNT(count, acc); // count-in remaining accumulator 
  1673. #endif
  1674.     return count;
  1675. }
  1676. /*!
  1677.     Function calculates number of times when bit value changed 
  1678.     (1-0 or 0-1).
  1679.     
  1680.     For 001 result is 2
  1681.         010 - 3
  1682.         011 - 2
  1683.         111 - 1
  1684.     
  1685.     @ingroup bitfunc 
  1686. */
  1687. inline 
  1688. bm::id_t bit_count_change(bm::word_t w)
  1689. {
  1690.     unsigned count = 1;
  1691.     w ^= (w >> 1);
  1692.     BM_INCWORD_BITCOUNT(count, w);
  1693.     count -= (w >> ((sizeof(w) * 8) - 1));
  1694.     return count;
  1695. }
  1696. /*!
  1697.     Function calculates number of times when bit value changed 
  1698.     (1-0 or 0-1) in the bit block.
  1699.         
  1700.     @ingroup bitfunc 
  1701. */
  1702. inline 
  1703. bm::id_t bit_block_calc_count_change(const bm::word_t* block, 
  1704.          const bm::word_t* block_end)
  1705. {
  1706.     BM_ASSERT(block < block_end);
  1707.     bm::id_t count = 1;
  1708.     
  1709. #ifdef BM64OPT
  1710.     // 64-bit optimized algorithm.
  1711.     const bm::id64_t* b1 = (bm::id64_t*) block;
  1712.     const bm::id64_t* b2 = (bm::id64_t*) block_end;
  1713.     bm::id64_t w, w0, w_prev, w_l;
  1714.     w = w0 = *b1;
  1715.     const int w_shift = sizeof(w) * 8 - 1;
  1716.     w ^= (w >> 1);
  1717.     count += word_bitcount64(w);
  1718.     count -= (w_prev = (w0 >> w_shift)); // negative value correction
  1719.     
  1720.     for (++b1 ;b1 < b2; ++b1)
  1721.     {
  1722.         w = w0 = *b1;
  1723.         ++count;
  1724.         
  1725.         if (!w)
  1726.         {
  1727.             count -= !w_prev;
  1728.             w_prev = 0;
  1729.         }
  1730.         else
  1731.         {
  1732.             w ^= (w >> 1);
  1733.             count += word_bitcount64(w);
  1734.             
  1735.             w_l = w0 & 1;
  1736.             count -= (w0 >> w_shift);  // negative value correction
  1737.             count -= !(w_prev ^ w_l);  // word border correction
  1738.             
  1739.             w_prev = (w0 >> w_shift);
  1740.         }
  1741.     } // for
  1742. #else
  1743.     
  1744.     bm::word_t  w, w0, w_prev, w_l; 
  1745.     
  1746.     w = w0 = *block;
  1747.     const int w_shift = sizeof(w) * 8 - 1;    
  1748.     w ^= (w >> 1);
  1749.     BM_INCWORD_BITCOUNT(count, w);
  1750.     count -= (w_prev = (w0 >> w_shift)); // negative value correction
  1751.     for (++block ;block < block_end; ++block)
  1752.     {
  1753.         w = w0 = *block;
  1754.         ++count;
  1755.         if (!w)
  1756.         {       
  1757.             count -= !w_prev;
  1758.             w_prev = 0;
  1759.         }
  1760.         else
  1761.         {
  1762.             w ^= (w >> 1);
  1763.             BM_INCWORD_BITCOUNT(count, w);
  1764.             
  1765.             w_l = w0 & 1;
  1766.             count -= (w0 >> w_shift);  // negative value correction
  1767.             count -= !(w_prev ^ w_l);  // word border correction
  1768.             
  1769.             w_prev = (w0 >> w_shift);
  1770.         }
  1771.     } // for
  1772. #endif
  1773.     return count;
  1774. }
  1775. /*!
  1776. Function calculates number of 1 bits in the given array of words in
  1777.     the range between left anf right bits (borders included)
  1778.     Make sure the addresses are aligned.
  1779.     @ingroup bitfunc
  1780. */
  1781. inline 
  1782. bm::id_t bit_block_calc_count_range(const bm::word_t* block,
  1783.                                     bm::word_t left,
  1784.                                     bm::word_t right)
  1785. {
  1786.     BM_ASSERT(left <= right);
  1787.     
  1788. bm::id_t count = 0;
  1789.     unsigned nbit  = left; // unsigned(left & bm::set_block_mask);
  1790.     unsigned nword = unsigned(nbit >> bm::set_word_shift);
  1791.     nbit &= bm::set_word_mask;
  1792.     const bm::word_t* word = block + nword;
  1793.     if (left == right)  // special case (only 1 bit to check)
  1794.     {
  1795.         return (*word >> nbit) & 1;
  1796.     }
  1797.     unsigned acc;
  1798.     unsigned bitcount = right - left + 1;
  1799.     if (nbit) // starting position is not aligned
  1800.     {
  1801.         unsigned right_margin = nbit + (right - left);
  1802.         if (right_margin < 32)
  1803.         {
  1804.             unsigned mask =
  1805.                 block_set_table<true>::_right[nbit] &
  1806.                 block_set_table<true>::_left[right_margin];
  1807.             acc = *word & mask;
  1808.             
  1809.             BM_INCWORD_BITCOUNT(count, acc);
  1810.             return count;
  1811.         }
  1812.         else
  1813.         {
  1814.             acc = *word & block_set_table<true>::_right[nbit];
  1815.             BM_INCWORD_BITCOUNT(count, acc);
  1816.             bitcount -= 32 - nbit;
  1817.         }
  1818.         ++word;
  1819.     }
  1820.     // now when we are word aligned, we can count bits the usual way
  1821.     for ( ;bitcount >= 32; bitcount -= 32)
  1822.     {
  1823.         acc = *word++;
  1824.         BM_INCWORD_BITCOUNT(count, acc);
  1825.     }
  1826.     if (bitcount)  // we have a tail to count
  1827.     {
  1828.         acc = (*word) & block_set_table<true>::_left[bitcount-1];
  1829.         BM_INCWORD_BITCOUNT(count, acc);
  1830.     }
  1831.     return count;
  1832. }
  1833. // ----------------------------------------------------------------------
  1834. /*! Function inverts block of bits 
  1835.     @ingroup bitfunc 
  1836. */
  1837. template<typename T> void bit_invert(T* start, T* end)
  1838. {
  1839. #ifdef BMVECTOPT
  1840.     VECT_INVERT_ARR(start, end);
  1841. #else
  1842.     do
  1843.     {
  1844.         start[0] = ~start[0];
  1845.         start[1] = ~start[1];
  1846.         start[2] = ~start[2];
  1847.         start[3] = ~start[3];
  1848.         start+=4;
  1849.     } while (start < end);
  1850. #endif
  1851. }
  1852. // ----------------------------------------------------------------------
  1853. /*! @brief Returns "true" if all bits in the block are 1
  1854.     @ingroup bitfunc 
  1855. */
  1856. inline bool is_bits_one(const bm::wordop_t* start, 
  1857.                         const bm::wordop_t* end)
  1858. {
  1859.    do
  1860.    {
  1861.         bm::wordop_t tmp = 
  1862.             start[0] & start[1] & start[2] & start[3];
  1863.         if (tmp != bm::all_bits_mask) 
  1864.             return false;
  1865.         start += 4;
  1866.    } while (start < end);
  1867.    return true;
  1868. }
  1869. // ----------------------------------------------------------------------
  1870. /*! @brief Returns "true" if all bits in the block are 0
  1871.     @ingroup bitfunc 
  1872. */
  1873. inline bool bit_is_all_zero(const bm::wordop_t* start, 
  1874.                             const bm::wordop_t* end)
  1875. {
  1876.    do
  1877.    {
  1878.         bm::wordop_t tmp = 
  1879.             start[0] | start[1] | start[2] | start[3];
  1880.        if (tmp) 
  1881.            return false;
  1882.        start += 4;
  1883.    } while (start < end);
  1884.    return true;
  1885. }
  1886. // ----------------------------------------------------------------------
  1887. // GAP blocks manipulation functions:
  1888. /*! brief GAP and functor */
  1889. inline unsigned and_op(unsigned v1, unsigned v2)
  1890. {
  1891.     return v1 & v2;
  1892. }
  1893. /*! brief GAP xor functor */
  1894. inline unsigned xor_op(unsigned v1, unsigned v2)
  1895. {
  1896.     return v1 ^ v2;
  1897. }
  1898. /*!
  1899.    brief GAP AND operation.
  1900.    
  1901.    Function performs AND logical oparation on gap vectors.
  1902.    If possible function put the result into vect1 and returns this
  1903.    pointer.  Otherwise result is put into tmp_buf, which should be 
  1904.    twice of the vector size.
  1905.    param vect1   - operand 1
  1906.    param vect2   - operand 2
  1907.    param tmp_buf - pointer on temporary buffer
  1908.    return Result pointer (tmp_buf OR vect1)
  1909.    @ingroup gapfunc
  1910. */
  1911. inline gap_word_t* gap_operation_and(const gap_word_t* BMRESTRICT vect1,
  1912.                                      const gap_word_t* BMRESTRICT vect2,
  1913.                                      gap_word_t*       BMRESTRICT tmp_buf)
  1914. {
  1915.     gap_buff_op(tmp_buf, vect1, 0, vect2, 0, and_op);
  1916.     return tmp_buf;
  1917. }
  1918. /*!
  1919.    brief GAP XOR operation.
  1920.    
  1921.    Function performs XOR logical oparation on gap vectors.
  1922.    If possible function put the result into vect1 and returns this
  1923.    pointer.  Otherwise result is put into tmp_buf, which should be 
  1924.    twice of the vector size.
  1925.    param vect1   - operand 1
  1926.    param vect2   - operand 2
  1927.    param tmp_buf - pointer on temporary buffer
  1928.    return Result pointer (tmp_buf)
  1929.    @ingroup gapfunc
  1930. */
  1931. inline gap_word_t* gap_operation_xor(const gap_word_t*  BMRESTRICT vect1,
  1932.                                      const gap_word_t*  BMRESTRICT vect2,
  1933.                                      gap_word_t*        BMRESTRICT tmp_buf)
  1934. {
  1935.     gap_buff_op(tmp_buf, vect1, 0, vect2, 0, xor_op);
  1936.     return tmp_buf;
  1937. }
  1938. /*!
  1939.    brief GAP OR operation.
  1940.    
  1941.    Function performs OR logical oparation on gap vectors.
  1942.    If possible function put the result into vect1 and returns this
  1943.    pointer.  Otherwise result is put into tmp_buf, which should be 
  1944.    twice of the vector size.
  1945.    param vect1   - operand 1
  1946.    param vect2   - operand 2
  1947.    param tmp_buf - pointer on temporary buffer
  1948.    return Result pointer (tmp_buf)
  1949.    @ingroup gapfunc
  1950. */
  1951. inline gap_word_t* gap_operation_or(const gap_word_t*  BMRESTRICT vect1,
  1952.                                     const gap_word_t*  BMRESTRICT vect2,
  1953.                                     gap_word_t*        BMRESTRICT tmp_buf)
  1954. {
  1955. //    gap_invert(vect1);
  1956. //    gap_temp_invert(vect2);
  1957.     gap_buff_op(tmp_buf, vect1, 1, vect2, 1, and_op);
  1958. //    gap_word_t* res = gap_operation_and(vect1, vect2, tmp_buf);
  1959. //    gap_temp_invert(vect2);
  1960.     gap_invert(tmp_buf);
  1961. //    gap_invert(vect1);
  1962.     
  1963.     return tmp_buf;
  1964. }
  1965. /*!
  1966.    brief GAP SUB (AND NOT) operation.
  1967.    
  1968.    Function performs SUB logical oparation on gap vectors.
  1969.    If possible function put the result into vect1 and returns this
  1970.    pointer.  Otherwise result is put into tmp_buf, which should be 
  1971.    twice of the vector size.
  1972.    param vect1   - operand 1
  1973.    param vect2   - operand 2
  1974.    param tmp_buf - pointer on temporary buffer
  1975.    return Result pointer (tmp_buf)
  1976.    @ingroup gapfunc
  1977. */
  1978. inline gap_word_t* gap_operation_sub(const gap_word_t*  BMRESTRICT vect1,
  1979.                                      const gap_word_t*  BMRESTRICT vect2,
  1980.                                      gap_word_t*        BMRESTRICT tmp_buf)
  1981. {
  1982. //    gap_temp_invert(vect2);
  1983.     
  1984.     gap_buff_op(tmp_buf, vect1, 0, vect2, 1, and_op);    
  1985. //    gap_word_t* res = gap_operation_and(vect1, vect2, tmp_buf);
  1986. //    gap_temp_invert(vect2);
  1987.     return tmp_buf;
  1988. }
  1989. // ----------------------------------------------------------------------
  1990. // BIT blocks manipulation functions:
  1991. /*!
  1992.    brief Bitblock copy operation. 
  1993.    param dst - destination block.
  1994.    param src - source block.
  1995.    @ingroup bitfunc
  1996. */
  1997. inline 
  1998. void bit_block_copy(bm::word_t* BMRESTRICT dst, const bm::word_t* BMRESTRICT src)
  1999. {
  2000. #ifdef BMVECTOPT
  2001.     VECT_COPY_BLOCK(dst, src, src + bm::set_block_size);
  2002. #else
  2003.     ::memcpy(dst, src, bm::set_block_size * sizeof(bm::word_t));
  2004. #endif
  2005. }
  2006. /*!
  2007.    brief Plain bitblock AND operation. 
  2008.    Function does not analyse availability of source and destination blocks.
  2009.    param dst - destination block.
  2010.    param src - source block.
  2011.    @ingroup bitfunc
  2012. */
  2013. inline 
  2014. void bit_block_and(bm::word_t* BMRESTRICT dst, const bm::word_t* BMRESTRICT src)
  2015. {
  2016. #ifdef BMVECTOPT
  2017.     VECT_AND_ARR(dst, src, src + bm::set_block_size);
  2018. #else
  2019.     const bm::wordop_t* BMRESTRICT wrd_ptr = (wordop_t*)src;
  2020.     const bm::wordop_t* BMRESTRICT wrd_end = (wordop_t*)(src + bm::set_block_size);
  2021.     bm::wordop_t* BMRESTRICT dst_ptr = (wordop_t*)dst;
  2022.     do
  2023.     {
  2024.         dst_ptr[0] &= wrd_ptr[0];
  2025.         dst_ptr[1] &= wrd_ptr[1];
  2026.         dst_ptr[2] &= wrd_ptr[2];
  2027.         dst_ptr[3] &= wrd_ptr[3];
  2028.         dst_ptr+=4;
  2029.         wrd_ptr+=4;
  2030.     } while (wrd_ptr < wrd_end);
  2031. #endif
  2032. }
  2033. /*!
  2034.    brief Function ANDs two bitblocks and computes the bitcount. 
  2035.    Function does not analyse availability of source blocks.
  2036.    param src1     - first bit block
  2037.    param src1_end - first bit block end
  2038.    param src2     - second bit block
  2039.    @ingroup bitfunc
  2040. */
  2041. inline 
  2042. unsigned bit_block_and_count(const bm::word_t* src1, 
  2043.                              const bm::word_t* src1_end,
  2044.                              const bm::word_t* src2)
  2045. {
  2046.     unsigned count;
  2047. #ifdef BMVECTOPT
  2048.     count = VECT_BITCOUNT_AND(src1, src1_end, src2);
  2049. #else  
  2050.     count = 0;  
  2051.     do
  2052.     {
  2053.         BM_INCWORD_BITCOUNT(count, src1[0] & src2[0]);
  2054.         BM_INCWORD_BITCOUNT(count, src1[1] & src2[1]);
  2055.         BM_INCWORD_BITCOUNT(count, src1[2] & src2[2]);
  2056.         BM_INCWORD_BITCOUNT(count, src1[3] & src2[3]);
  2057.         src1+=4;
  2058.         src2+=4;
  2059.     } while (src1 < src1_end);
  2060. #endif    
  2061.     return count;
  2062. }
  2063. /*!
  2064.    brief Function XORs two bitblocks and computes the bitcount. 
  2065.    Function does not analyse availability of source blocks.
  2066.    param src1     - first bit block.
  2067.    param src1_end - first bit block end
  2068.    param src2     - second bit block.
  2069.    @ingroup bitfunc
  2070. */
  2071. inline 
  2072. unsigned bit_block_xor_count(const bm::word_t* BMRESTRICT src1,
  2073.                              const bm::word_t* BMRESTRICT src1_end, 
  2074.                              const bm::word_t* BMRESTRICT src2)
  2075. {
  2076.     unsigned count;
  2077. #ifdef BMVECTOPT
  2078.     count = VECT_BITCOUNT_XOR(src1, src1_end, src2);
  2079. #else  
  2080.     count = 0;  
  2081.     do
  2082.     {
  2083.         BM_INCWORD_BITCOUNT(count, src1[0] ^ src2[0]);
  2084.         BM_INCWORD_BITCOUNT(count, src1[1] ^ src2[1]);
  2085.         BM_INCWORD_BITCOUNT(count, src1[2] ^ src2[2]);
  2086.         BM_INCWORD_BITCOUNT(count, src1[3] ^ src2[3]);
  2087.         src1+=4;
  2088.         src2+=4;
  2089.     } while (src1 < src1_end);
  2090. #endif
  2091.     return count;
  2092. }
  2093. /*!
  2094.    brief Function SUBs two bitblocks and computes the bitcount. 
  2095.    Function does not analyse availability of source blocks.
  2096.    param src1     - first bit block.
  2097.    param src1_end - first bit block end
  2098.    param src2     - second bit block.
  2099.    @ingroup bitfunc
  2100. */
  2101. inline 
  2102. unsigned bit_block_sub_count(const bm::word_t* BMRESTRICT src1, 
  2103.                              const bm::word_t* BMRESTRICT src1_end, 
  2104.                              const bm::word_t* BMRESTRICT src2)
  2105. {
  2106.     unsigned count;
  2107. #ifdef BMVECTOPT
  2108.     count = VECT_BITCOUNT_SUB(src1, src1_end, src2);
  2109. #else  
  2110.     count = 0;  
  2111.     do
  2112.     {
  2113.         BM_INCWORD_BITCOUNT(count, src1[0] & ~src2[0]);
  2114.         BM_INCWORD_BITCOUNT(count, src1[1] & ~src2[1]);
  2115.         BM_INCWORD_BITCOUNT(count, src1[2] & ~src2[2]);
  2116.         BM_INCWORD_BITCOUNT(count, src1[3] & ~src2[3]);
  2117.         src1+=4;
  2118.         src2+=4;
  2119.     } while (src1 < src1_end);
  2120. #endif
  2121.     return count;
  2122. }
  2123. /*!
  2124.    brief Function ORs two bitblocks and computes the bitcount. 
  2125.    Function does not analyse availability of source blocks.
  2126.    param src1     - first bit block
  2127.    param src1_end - first block end
  2128.    param src2     - second bit block.
  2129.    @ingroup bitfunc
  2130. */
  2131. inline 
  2132. unsigned bit_block_or_count(const bm::word_t* src1, 
  2133.                             const bm::word_t* src1_end,
  2134.                             const bm::word_t* src2)
  2135. {
  2136.     unsigned count;
  2137. #ifdef BMVECTOPT
  2138.     count = VECT_BITCOUNT_OR(src1, src1_end, src2);
  2139. #else  
  2140.     count = 0;  
  2141.     do
  2142.     {
  2143.         BM_INCWORD_BITCOUNT(count, src1[0] | src2[0]);
  2144.         BM_INCWORD_BITCOUNT(count, src1[1] | src2[1]);
  2145.         BM_INCWORD_BITCOUNT(count, src1[2] | src2[2]);
  2146.         BM_INCWORD_BITCOUNT(count, src1[3] | src2[3]);
  2147.         src1+=4;
  2148.         src2+=4;
  2149.     } while (src1 < src1_end);
  2150. #endif
  2151.     return count;
  2152. }
  2153. /*!
  2154.    brief bitblock AND operation. 
  2155.    param dst - destination block.
  2156.    param src - source block.
  2157.    returns pointer on destination block. 
  2158.     If returned value  equal to src means that block mutation requested. 
  2159.     NULL is valid return value.
  2160.    @ingroup bitfunc
  2161. */
  2162. inline bm::word_t* bit_operation_and(bm::word_t* BMRESTRICT dst, 
  2163.                                      const bm::word_t* BMRESTRICT src)
  2164. {
  2165.     BM_ASSERT(dst || src);
  2166.     bm::word_t* ret = dst;
  2167.     if (IS_VALID_ADDR(dst))  // The destination block already exists
  2168.     {
  2169.         if (!IS_VALID_ADDR(src))
  2170.         {
  2171.             if (IS_EMPTY_BLOCK(src))
  2172.             {
  2173.                 //If the source block is zero 
  2174.                 //just clean the destination block
  2175.                 return 0;
  2176.             }
  2177.         }
  2178.         else
  2179.         {
  2180.             // Regular operation AND on the whole block.
  2181.             bit_block_and(dst, src);
  2182.         }
  2183.     }
  2184.     else // The destination block does not exist yet
  2185.     {
  2186.         if(!IS_VALID_ADDR(src))
  2187.         {
  2188.             if(IS_EMPTY_BLOCK(src)) 
  2189.             {
  2190.                 // The source block is empty.
  2191.                 // One argument empty - all result is empty.
  2192.                 return 0;
  2193.             }
  2194.             // Here we have nothing to do.
  2195.             // Src block is all ON, dst block remains as it is
  2196.         }
  2197.         else // destination block does not exists, src - valid block
  2198.         {
  2199.             if (IS_FULL_BLOCK(dst))
  2200.             {
  2201.                 return const_cast<bm::word_t*>(src);
  2202.             }
  2203.             // Nothng to do.
  2204.             // Dst block is all ZERO no combination required.
  2205.         }
  2206.     }
  2207.     return ret;
  2208. }
  2209. /*!
  2210.    brief Performs bitblock AND operation and calculates bitcount of the result. 
  2211.    param src1     - first bit block.
  2212.    param src1_end - first bit block end
  2213.    param src2     - second bit block.
  2214.    returns bitcount value 
  2215.    @ingroup bitfunc
  2216. */
  2217. inline 
  2218. bm::id_t bit_operation_and_count(const bm::word_t* BMRESTRICT src1,
  2219.                                  const bm::word_t* BMRESTRICT src1_end,
  2220.                                  const bm::word_t* BMRESTRICT src2)
  2221. {
  2222.     if (IS_EMPTY_BLOCK(src1) || IS_EMPTY_BLOCK(src2))
  2223.     {
  2224.         return 0;
  2225.     }
  2226.     return bit_block_and_count(src1, src1_end, src2);
  2227. }
  2228. /*!
  2229.    brief Performs bitblock SUB operation and calculates bitcount of the result. 
  2230.    param src1      - first bit block.
  2231.    param src1_end  - first bit block end
  2232.    param src2      - second bit block
  2233.    returns bitcount value 
  2234.    @ingroup bitfunc
  2235. */
  2236. inline 
  2237. bm::id_t bit_operation_sub_count(const bm::word_t* BMRESTRICT src1, 
  2238.                                  const bm::word_t* BMRESTRICT src1_end,
  2239.                                  const bm::word_t* BMRESTRICT src2)
  2240. {
  2241.     if (IS_EMPTY_BLOCK(src1))
  2242.     {
  2243.         return 0;
  2244.     }
  2245.     
  2246.     if (IS_EMPTY_BLOCK(src2)) // nothing to diff
  2247.     {
  2248.         return bit_block_calc_count(src1, src1_end);
  2249.     }
  2250.     return bit_block_sub_count(src1, src1_end, src2);
  2251. }
  2252. /*!
  2253.    brief Performs bitblock OR operation and calculates bitcount of the result. 
  2254.    param src1     - first bit block.
  2255.    param src1_end - first bit block end
  2256.    param src2     - second bit block.
  2257.    returns bitcount value 
  2258.    @ingroup bitfunc
  2259. */
  2260. inline 
  2261. bm::id_t bit_operation_or_count(const bm::word_t* BMRESTRICT src1,
  2262.                                 const bm::word_t* BMRESTRICT src1_end, 
  2263.                                 const bm::word_t* BMRESTRICT src2)
  2264. {
  2265.     if (IS_EMPTY_BLOCK(src1))
  2266.     {
  2267.         if (!IS_EMPTY_BLOCK(src2))
  2268.             return bit_block_calc_count(src2, src2 + (src1_end - src1));
  2269.         else
  2270.             return 0; // both blocks are empty        
  2271.     }
  2272.     else
  2273.     {
  2274.         if (IS_EMPTY_BLOCK(src2))
  2275.             return bit_block_calc_count(src1, src1_end);
  2276.     }
  2277.     return bit_block_or_count(src1, src1_end, src2);
  2278. }
  2279. /*!
  2280.    brief Plain bitblock OR operation. 
  2281.    Function does not analyse availability of source and destination blocks.
  2282.    param dst - destination block.
  2283.    param src - source block.
  2284.    @ingroup bitfunc
  2285. */
  2286. inline void bit_block_or(bm::word_t* BMRESTRICT dst, 
  2287.                          const bm::word_t* BMRESTRICT src)
  2288. {
  2289. #ifdef BMVECTOPT
  2290.     VECT_OR_ARR(dst, src, src + bm::set_block_size);
  2291. #else
  2292.     const bm::wordop_t* BMRESTRICT wrd_ptr = (wordop_t*)src;
  2293.     const bm::wordop_t* BMRESTRICT wrd_end = (wordop_t*)(src + set_block_size);
  2294.     bm::wordop_t* BMRESTRICT dst_ptr = (wordop_t*)dst;
  2295.     do
  2296.     {
  2297.         dst_ptr[0] |= wrd_ptr[0];
  2298.         dst_ptr[1] |= wrd_ptr[1];
  2299.         dst_ptr[2] |= wrd_ptr[2];
  2300.         dst_ptr[3] |= wrd_ptr[3];
  2301.         dst_ptr+=4;
  2302.         wrd_ptr+=4;
  2303.     } while (wrd_ptr < wrd_end);
  2304. #endif
  2305. }
  2306. /*!
  2307.    brief Block OR operation. Makes analysis if block is 0 or FULL. 
  2308.    param dst - destination block.
  2309.    param src - source block.
  2310.    returns pointer on destination block. 
  2311.     If returned value  equal to src means that block mutation requested. 
  2312.     NULL is valid return value.
  2313.    @ingroup bitfunc
  2314. */
  2315. inline 
  2316. bm::word_t* bit_operation_or(bm::word_t* BMRESTRICT dst, 
  2317.                              const bm::word_t* BMRESTRICT src)
  2318. {
  2319.     BM_ASSERT(dst || src);
  2320.     bm::word_t* ret = dst;
  2321.     if (IS_VALID_ADDR(dst)) // The destination block already exists
  2322.     {
  2323.         if (!IS_VALID_ADDR(src))
  2324.         {
  2325.             if (IS_FULL_BLOCK(src))
  2326.             {
  2327.                 // if the source block is all set 
  2328.                 // just set the destination block
  2329.                 ::memset(dst, 0xFF, bm::set_block_size * sizeof(bm::word_t));
  2330.             }
  2331.         }
  2332.         else
  2333.         {
  2334.             // Regular operation OR on the whole block
  2335.             bit_block_or(dst, src);
  2336.         }
  2337.     }
  2338.     else // The destination block does not exist yet
  2339.     {
  2340.         if (!IS_VALID_ADDR(src))
  2341.         {
  2342.             if (IS_FULL_BLOCK(src)) 
  2343.             {
  2344.                 // The source block is all set, because dst does not exist
  2345.                 // we can simply replace it.
  2346.                 return const_cast<bm::word_t*>(FULL_BLOCK_ADDR);
  2347.             }
  2348.         }
  2349.         else
  2350.         {
  2351.             if (dst == 0)
  2352.             {
  2353.                 // The only case when we have to allocate the new block:
  2354.                 // Src is all zero and Dst does not exist
  2355.                 return const_cast<bm::word_t*>(src);
  2356.             }
  2357.         }
  2358.     }
  2359.     return ret;
  2360. }
  2361. /*!
  2362.    brief Plain bitblock SUB (AND NOT) operation. 
  2363.    Function does not analyse availability of source and destination blocks.
  2364.    param dst - destination block.
  2365.    param src - source block.
  2366.    @ingroup bitfunc
  2367. */
  2368. inline 
  2369. void bit_block_sub(bm::word_t* BMRESTRICT dst, 
  2370.                    const bm::word_t* BMRESTRICT src)
  2371. {
  2372. #ifdef BMVECTOPT
  2373.     VECT_SUB_ARR(dst, src, src + bm::set_block_size);
  2374. #else
  2375.     const bm::wordop_t* BMRESTRICT wrd_ptr = (wordop_t*) src;
  2376.     const bm::wordop_t* BMRESTRICT wrd_end = 
  2377.                      (wordop_t*) (src + bm::set_block_size);
  2378.     bm::wordop_t* dst_ptr = (wordop_t*)dst;
  2379.     
  2380.     // Regular operation AND-NOT on the whole block.
  2381.     do
  2382.     {
  2383.         dst_ptr[0] &= ~wrd_ptr[0];
  2384.         dst_ptr[1] &= ~wrd_ptr[1];
  2385.         dst_ptr[2] &= ~wrd_ptr[2];
  2386.         dst_ptr[3] &= ~wrd_ptr[3];
  2387.         dst_ptr+=4;
  2388.         wrd_ptr+=4;
  2389.     } while (wrd_ptr < wrd_end);
  2390. #endif
  2391.     
  2392. }
  2393. /*!
  2394.    brief bitblock SUB operation. 
  2395.    param dst - destination block.
  2396.    param src - source block.
  2397.    returns pointer on destination block. 
  2398.     If returned value  equal to src means that block mutation requested. 
  2399.     NULL is valid return value.
  2400.    @ingroup bitfunc
  2401. */
  2402. inline 
  2403. bm::word_t* bit_operation_sub(bm::word_t* BMRESTRICT dst, 
  2404.                               const bm::word_t* BMRESTRICT src)
  2405. {
  2406.     BM_ASSERT(dst || src);
  2407.     bm::word_t* ret = dst;
  2408.     if (IS_VALID_ADDR(dst))  //  The destination block already exists
  2409.     {
  2410.         if (!IS_VALID_ADDR(src))
  2411.         {
  2412.             if (IS_FULL_BLOCK(src))
  2413.             {
  2414.                 // If the source block is all set
  2415.                 // just clean the destination block
  2416.                 return 0;
  2417.             }
  2418.         }
  2419.         else
  2420.         {
  2421.             bit_block_sub(dst, src);
  2422.         }
  2423.     }
  2424.     else // The destination block does not exist yet
  2425.     {
  2426.         if (!IS_VALID_ADDR(src))
  2427.         {
  2428.             if (IS_FULL_BLOCK(src)) 
  2429.             {
  2430.                 // The source block is full
  2431.                 return 0;
  2432.             }
  2433.         }
  2434.         else
  2435.         {
  2436.             if (IS_FULL_BLOCK(dst))
  2437.             {
  2438.                 // The only case when we have to allocate the new block:
  2439.                 // dst is all set and src exists
  2440.                 return const_cast<bm::word_t*>(src);                  
  2441.             }
  2442.         }
  2443.     }
  2444.     return ret;
  2445. }
  2446. /*!
  2447.    brief Plain bitblock XOR operation. 
  2448.    Function does not analyse availability of source and destination blocks.
  2449.    param dst - destination block.
  2450.    param src - source block.
  2451.    @ingroup bitfunc
  2452. */
  2453. inline 
  2454. void bit_block_xor(bm::word_t* BMRESTRICT dst, 
  2455.                    const bm::word_t* BMRESTRICT src)
  2456. {
  2457. #ifdef BMVECTOPT
  2458.     VECT_XOR_ARR(dst, src, src + bm::set_block_size);
  2459. #else
  2460.     const bm::wordop_t* BMRESTRICT wrd_ptr = (wordop_t*) src;
  2461.     const bm::wordop_t* BMRESTRICT wrd_end = 
  2462.                             (wordop_t*) (src + bm::set_block_size);
  2463.     bm::wordop_t* BMRESTRICT dst_ptr = (wordop_t*)dst;
  2464.     // Regular XOR operation on the whole block.
  2465.     do
  2466.     {
  2467.         dst_ptr[0] ^= wrd_ptr[0];
  2468.         dst_ptr[1] ^= wrd_ptr[1];
  2469.         dst_ptr[2] ^= wrd_ptr[2];
  2470.         dst_ptr[3] ^= wrd_ptr[3];
  2471.         dst_ptr+=4;
  2472.         wrd_ptr+=4;
  2473.     } while (wrd_ptr < wrd_end);
  2474. #endif
  2475.     
  2476. }
  2477. /*!
  2478.    brief bitblock XOR operation. 
  2479.    param dst - destination block.
  2480.    param src - source block.
  2481.    returns pointer on destination block. 
  2482.     If returned value  equal to src means that block mutation requested. 
  2483.     NULL is valid return value.
  2484.    @ingroup bitfunc
  2485. */
  2486. inline 
  2487. bm::word_t* bit_operation_xor(bm::word_t* BMRESTRICT dst, 
  2488.                               const bm::word_t* BMRESTRICT src)
  2489. {
  2490.     BM_ASSERT(dst || src);
  2491.     if (src == dst) return 0;  // XOR rule  
  2492.     bm::word_t* ret = dst;
  2493.     if (IS_VALID_ADDR(dst))  //  The destination block already exists
  2494.     {           
  2495.         if (!src) return dst;
  2496.         
  2497.         bit_block_xor(dst, src);
  2498.     }
  2499.     else // The destination block does not exist yet
  2500.     {
  2501.         if (!src) return dst;      // 1 xor 0 = 1
  2502.         // Here we have two cases:
  2503.         // if dest block is full or zero if zero we need to copy the source
  2504.         // otherwise XOR loop against 0xFF...
  2505.         //BM_ASSERT(dst == 0);
  2506.         return const_cast<bm::word_t*>(src);  // src is the final result               
  2507.     }
  2508.     return ret;
  2509. }
  2510. /*!
  2511.    brief Performs bitblock XOR operation and calculates bitcount of the result. 
  2512.    param src1 - first bit block.
  2513.    param src2 - second bit block.
  2514.    returns bitcount value 
  2515.    @ingroup bitfunc
  2516. */
  2517. inline 
  2518. bm::id_t bit_operation_xor_count(const bm::word_t* BMRESTRICT src1,
  2519.                                  const bm::word_t* BMRESTRICT src1_end,
  2520.                                  const bm::word_t* BMRESTRICT src2)
  2521. {
  2522.     if (IS_EMPTY_BLOCK(src1) || IS_EMPTY_BLOCK(src2))
  2523.     {
  2524.         if (IS_EMPTY_BLOCK(src1) && IS_EMPTY_BLOCK(src2))
  2525.             return 0;
  2526.         const bm::word_t* block = IS_EMPTY_BLOCK(src1) ? src2 : src1;
  2527.         return bit_block_calc_count(block, block + (src1_end - src1));
  2528.     }
  2529.     return bit_block_xor_count(src1, src1_end, src2);
  2530. }
  2531. //------------------------------------------------------------------------
  2532. /**
  2533.     brief Searches for the next 1 bit in the BIT block
  2534.     param data - BIT buffer
  2535.     param nbit - bit index to start checking from
  2536.     param prev - returns previously checked value
  2537.     @ingroup bitfunc
  2538. */
  2539. inline 
  2540. int bit_find_in_block(const bm::word_t* data, 
  2541.                       unsigned nbit, 
  2542.                       bm::id_t* prev)
  2543. {
  2544.     register bm::id_t p = *prev;
  2545.     int found = 0;
  2546.     for(;;)
  2547.     {
  2548.         unsigned nword  = nbit >> bm::set_word_shift;
  2549.         if (nword >= bm::set_block_size) break;
  2550.         register bm::word_t val = data[nword] >> (p & bm::set_word_mask);
  2551.         if (val)
  2552.         {
  2553.             while((val & 1) == 0)
  2554.             {
  2555.                 val >>= 1;
  2556.                 ++nbit;
  2557.                 ++p;
  2558.             }
  2559.             ++found;
  2560.             break;
  2561.         }
  2562.         else
  2563.         {
  2564.            p    += (bm::set_word_mask + 1) - (nbit & bm::set_word_mask);
  2565.            nbit += (bm::set_word_mask + 1) - (nbit & bm::set_word_mask);
  2566.         }
  2567.     }
  2568.     *prev = p;
  2569.     return found;
  2570. }
  2571. /*!
  2572.    brief Unpacks word into list of ON bit indexes
  2573.    param w - value
  2574.    param bits - pointer on the result array 
  2575.    return number of bits in the list
  2576.    @ingroup bitfunc
  2577. */
  2578. template<typename T,typename B> unsigned bit_list(T w, B* bits)
  2579. {
  2580.     // Note: 4-bit table method works slower than plain check approach
  2581.     unsigned octet = 0;
  2582.     B*       bp = bits;
  2583.     do
  2584.     {
  2585.         if (w & 1)   *bp++ = octet + 0;
  2586.         if (w & 2)   *bp++ = octet + 1;
  2587.         if (w & 4)   *bp++ = octet + 2;
  2588.         if (w & 8)   *bp++ = octet + 3;
  2589.         if (w & 16)  *bp++ = octet + 4;
  2590.         if (w & 32)  *bp++ = octet + 5;
  2591.         if (w & 64)  *bp++ = octet + 6;
  2592.         if (w & 128) *bp++ = octet + 7;
  2593.         w >>= 8;
  2594.         octet += 8;
  2595.     } while (w);
  2596.     return bp - bits;
  2597. }
  2598. /*! @brief Calculates memory overhead for number of gap blocks sharing 
  2599.            the same memory allocation table (level lengths table).
  2600.     @ingroup gapfunc
  2601. */
  2602. template<typename T> 
  2603. unsigned gap_overhead(const T* length, 
  2604.                       const T* length_end, 
  2605.                       const T* glevel_len)
  2606. {
  2607.     BM_ASSERT(length && length_end && glevel_len);
  2608.     unsigned overhead = 0;
  2609.     for (;length < length_end; ++length)
  2610.     {
  2611.         unsigned len = *length;
  2612.         int level = gap_calc_level(len, glevel_len);
  2613.         BM_ASSERT(level >= 0 && level < (int)bm::gap_levels);
  2614.         unsigned capacity = glevel_len[level];
  2615.         BM_ASSERT(capacity >= len);
  2616.         overhead += capacity - len;
  2617.     }
  2618.     return overhead;
  2619. }
  2620. /*! @brief Finds optimal gap blocks lengths.
  2621.     @param length - first element of GAP lengths array
  2622.     @param length_end - end of the GAP lengths array
  2623.     @param glevel_len - destination GAP lengths array
  2624.     @ingroup gapfunc
  2625. */
  2626. template<typename T>
  2627. bool improve_gap_levels(const T* length,
  2628.                         const T* length_end,
  2629.                         T*       glevel_len)
  2630. {
  2631.     BM_ASSERT(length && length_end && glevel_len);
  2632.     size_t lsize = length_end - length;
  2633.     BM_ASSERT(lsize);
  2634.     
  2635.     gap_word_t max_len = 0;
  2636.     unsigned i;
  2637.     for (i = 0; i < lsize; ++i)
  2638.     {
  2639.         if (length[i] > max_len)
  2640.             max_len = length[i];
  2641.     }
  2642.     if (max_len < 5 || lsize <= bm::gap_levels)
  2643.     {
  2644.         glevel_len[0] = max_len + 4;
  2645.         for (i = 1; i < bm::gap_levels; ++i)
  2646.         {
  2647.             glevel_len[i] = bm::gap_max_buff_len;
  2648.         }
  2649.         return true;
  2650.     }
  2651.     glevel_len[bm::gap_levels-1] = max_len + 5;
  2652.     unsigned min_overhead = gap_overhead(length, length_end, glevel_len);
  2653.     bool is_improved = false;
  2654.     gap_word_t prev_value = glevel_len[bm::gap_levels-1];
  2655.     //
  2656.     // main problem solving loop
  2657.     //
  2658.     for (i = bm::gap_levels-2; ; --i)
  2659.     {
  2660.         unsigned opt_len = 0;
  2661.         unsigned j;
  2662.         bool imp_flag = false;
  2663.         gap_word_t gap_saved_value = glevel_len[i];
  2664.         for (j = 0; j < lsize; ++j)
  2665.         {
  2666. //            if (length[j]+4 > prev_value)
  2667. //                continue;
  2668.             
  2669.             glevel_len[i] = length[j]+4;
  2670.             unsigned ov = gap_overhead(length, length_end, glevel_len);
  2671.             if (ov <= min_overhead)
  2672.             {
  2673.                 min_overhead = ov;                
  2674.                 opt_len = length[j]+4;
  2675.                 imp_flag = true;
  2676.             }
  2677.         }
  2678.         if (imp_flag) {
  2679.             glevel_len[i] = opt_len; // length[opt_idx]+4;
  2680.             is_improved = true;
  2681.         }
  2682.         else 
  2683.         {
  2684.             glevel_len[i] = gap_saved_value;
  2685.         }
  2686.         if (i == 0) 
  2687.             break;
  2688.         prev_value = glevel_len[i];
  2689.     }
  2690.     // 
  2691.     // Remove duplicates
  2692.     //
  2693.     T val = *glevel_len;
  2694.     T* gp = glevel_len;
  2695.     T* res = glevel_len;
  2696.     for (i = 0; i < bm::gap_levels; ++i)
  2697.     {
  2698.         if (val != *gp)
  2699.         {
  2700.             val = *gp;
  2701.             *++res = val;
  2702.         }
  2703.         ++gp;
  2704.     }
  2705.     // Filling the "unused" part with max. possible value
  2706.     while (++res < (glevel_len + bm::gap_levels)) 
  2707.     {
  2708.         *res = bm::gap_max_buff_len;
  2709.     }
  2710.     return is_improved;
  2711. }
  2712. } // namespace bm
  2713. #endif