include/util/bitset/bmfunc.h

Go to the documentation of this file.
00001 #ifndef BMFUNC__H__INCLUDED__
00002 #define BMFUNC__H__INCLUDED__
00003 /*
00004 Copyright(c) 2002-2009 Anatoliy Kuznetsov(anatoliy_kuznetsov at yahoo.com)
00005 
00006 Permission is hereby granted, free of charge, to any person 
00007 obtaining a copy of this software and associated documentation 
00008 files (the "Software"), to deal in the Software without restriction, 
00009 including without limitation the rights to use, copy, modify, merge, 
00010 publish, distribute, sublicense, and/or sell copies of the Software, 
00011 and to permit persons to whom the Software is furnished to do so, 
00012 subject to the following conditions:
00013 
00014 The above copyright notice and this permission notice shall be included 
00015 in all copies or substantial portions of the Software.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
00018 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
00019 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
00020 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
00021 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
00022 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
00023 OTHER DEALINGS IN THE SOFTWARE.
00024 
00025 For more information please visit:  http://bmagic.sourceforge.net
00026 
00027 */
00028 
00029 #include <memory.h>
00030 
00031 #include "bmdef.h"
00032 #include "bmutil.h"
00033 
00034 
00035 #ifdef _MSC_VER
00036 # pragma warning( disable: 4146 )
00037 #endif
00038 
00039 namespace bm
00040 {
00041 
00042 
00043 /*!
00044     @brief Structure with statistical information about bitset's memory 
00045             allocation details. 
00046     @ingroup bvector
00047 */
00048 struct bv_statistics
00049 {
00050     /// Number of bit blocks.
00051     unsigned bit_blocks; 
00052     /// Number of GAP blocks.
00053     unsigned gap_blocks;  
00054     /// Estimated maximum of memory required for serialization.
00055     unsigned max_serialize_mem;
00056     /// Memory used by bitvector including temp and service blocks
00057     unsigned  memory_used;
00058     /// Array of all GAP block lengths in the bvector.
00059     gap_word_t   gap_length[bm::set_total_blocks];
00060     /// GAP lengths used by bvector
00061     gap_word_t  gap_levels[bm::gap_levels];
00062 
00063 
00064 
00065     /// cound bit block
00066     void add_bit_block()
00067     {
00068         ++bit_blocks;
00069         unsigned mem_used = sizeof(bm::word_t) * bm::set_block_size;
00070         memory_used += mem_used;
00071         max_serialize_mem += mem_used;
00072     }
00073 
00074     /// count gap block
00075     void add_gap_block(unsigned capacity, unsigned length)
00076     {
00077         ++gap_blocks;
00078         unsigned mem_used = capacity * sizeof(gap_word_t);
00079         memory_used += mem_used;
00080         max_serialize_mem += length * sizeof(gap_word_t);
00081     }
00082 };
00083 
00084 
00085 /*! @defgroup gapfunc GAP functions
00086  *  GAP functions implement different opereations on GAP compressed blocks
00087  *  and serve as a minimal building blocks.
00088  *  @ingroup bmagic
00089  *
00090  */
00091 
00092 /*! @defgroup bitfunc BIT functions
00093  *  Bit functions implement different opereations on bit blocks
00094  *  and serve as a minimal building blocks.
00095  *  @ingroup bmagic
00096  */
00097 
00098 
00099 /*! @brief Default GAP lengths table.
00100     @ingroup gapfunc
00101 */
00102 template<bool T> struct gap_len_table
00103 {
00104     static const gap_word_t _len[bm::gap_levels];
00105 };
00106 
00107 template<bool T>
00108 const gap_word_t gap_len_table<T>::_len[bm::gap_levels] = 
00109                 { 128, 256, 512, bm::gap_max_buff_len }; 
00110 
00111 
00112 /*! @brief Alternative GAP lengths table. 
00113     Good for for memory saver mode and very sparse bitsets.
00114 
00115     @ingroup gapfunc
00116 */
00117 template<bool T> struct gap_len_table_min
00118 {
00119     static const gap_word_t _len[bm::gap_levels];
00120 };
00121 
00122 template<bool T>
00123 const gap_word_t gap_len_table_min<T>::_len[bm::gap_levels] = 
00124                                 { 32, 96, 128, 512 }; 
00125 
00126 
00127 
00128 //---------------------------------------------------------------------
00129 
00130 /** Structure keeps all-left/right ON bits masks. 
00131     @ingroup bitfunc 
00132 */
00133 template<bool T> struct block_set_table
00134 {
00135     static const unsigned _left[32];
00136     static const unsigned _right[32];
00137 };
00138 
00139 template<bool T>
00140 const unsigned block_set_table<T>::_left[32] = {
00141     0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff,
00142     0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff, 0x1ffff, 0x3ffff, 0x7ffff,
00143     0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff,
00144     0x7ffffff, 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff
00145 };
00146 
00147 template<bool T>
00148 const unsigned block_set_table<T>::_right[32] = {
00149     0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8, 0xfffffff0,
00150     0xffffffe0, 0xffffffc0, 0xffffff80, 0xffffff00, 0xfffffe00,
00151     0xfffffc00, 0xfffff800, 0xfffff000, 0xffffe000, 0xffffc000,
00152     0xffff8000, 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
00153     0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, 0xff000000,
00154     0xfe000000, 0xfc000000, 0xf8000000, 0xf0000000, 0xe0000000,
00155     0xc0000000, 0x80000000
00156 };
00157 
00158 
00159 
00160 /*!
00161     Returns bit count
00162     @ingroup bitfunc 
00163 */
00164 BMFORCEINLINE
00165 bm::id_t word_bitcount(bm::id_t w)
00166 {
00167     return
00168     bm::bit_count_table<true>::_count[(unsigned char)(w)] + 
00169     bm::bit_count_table<true>::_count[(unsigned char)((w) >> 8)] + 
00170     bm::bit_count_table<true>::_count[(unsigned char)((w) >> 16)] + 
00171     bm::bit_count_table<true>::_count[(unsigned char)((w) >> 24)];
00172 }
00173 
00174 inline
00175 unsigned parallel_popcnt_32(unsigned b)
00176 {
00177     b = (b & 0x55555555) + (b >> 1 & 0x55555555);
00178     b = (b & 0x33333333) + (b >> 2 & 0x33333333);
00179     b = b + ((b >> 4) & 0x0F0F0F0F);
00180     b = b + (b >> 8);
00181     b = b + ((b >> 16) & 0x0000003F);
00182     return b;
00183 }
00184 
00185 
00186 #ifdef BM64OPT
00187 /*! 
00188     Function calculates number of 1 bits in 64-bit word.
00189     @ingroup bitfunc 
00190 */
00191 inline bm::id_t word_bitcount64(bm::id64_t w)
00192 {
00193     w = (w & 0x5555555555555555LU) + (w >> 1 & 0x5555555555555555LU);
00194     w = (w & 0x3333333333333333LU) + (w >> 2 & 0x3333333333333333LU);
00195     w = w + (w >> 4) & 0x0F0F0F0F0F0F0F0FLU;
00196     w = w + (w >> 8);
00197     w = w + (w >> 16);
00198     w = w + (w >> 32) & 0x0000007F;
00199     return (bm::id_t)w;
00200 }
00201 #endif
00202 
00203 
00204 
00205 //---------------------------------------------------------------------
00206 
00207 /**
00208     Nomenclature of set operations
00209 */
00210 enum set_operation
00211 {
00212     set_AND         = 0,
00213     set_OR          = 1,
00214     set_SUB         = 2,
00215     set_XOR         = 3,
00216     set_ASSIGN      = 4,
00217     set_COUNT       = 5,
00218     set_COUNT_AND   = 6,
00219     set_COUNT_XOR   = 7,
00220     set_COUNT_OR    = 8,
00221     set_COUNT_SUB_AB= 9,
00222     set_COUNT_SUB_BA= 10,
00223     set_COUNT_A     = 11,
00224     set_COUNT_B     = 12,
00225 
00226     set_END
00227 };
00228 
00229 /// Returns true if set operation is constant (bitcount)
00230 inline
00231 bool is_const_set_operation(set_operation op)
00232 {
00233     return (int(op) >= int(set_COUNT));
00234 }
00235 
00236 /**
00237     Bit operations enumeration.
00238 */
00239 enum operation
00240 {
00241     BM_AND = set_AND,
00242     BM_OR  = set_OR,
00243     BM_SUB = set_SUB,
00244     BM_XOR = set_XOR
00245 };
00246 
00247 /**
00248     Convert set operation to operation
00249 */
00250 inline
00251 bm::operation setop2op(bm::set_operation op)
00252 {
00253     BM_ASSERT(op == set_AND || 
00254               op == set_OR  || 
00255               op == set_SUB || 
00256               op == set_XOR);
00257     return (bm::operation) op;
00258 }
00259 
00260 //---------------------------------------------------------------------
00261 
00262 /** 
00263     Structure carries pointer on bit block with all bits 1
00264     @ingroup bitfunc 
00265 */
00266 template<bool T> struct all_set
00267 {
00268     struct BM_ALIGN16 all_set_block
00269     {
00270         bm::word_t _p[bm::set_block_size] BM_ALIGN16ATTR;
00271 
00272         all_set_block()
00273         {
00274             ::memset(_p, 0xFF, sizeof(_p));
00275         }
00276     };
00277 
00278     static all_set_block  _block;
00279 };
00280 
00281 
00282 template<bool T> typename all_set<T>::all_set_block all_set<T>::_block;
00283 
00284 /// XOR swap two scalar variables
00285 template<typename W> 
00286 void xor_swap(W& x, W& y) 
00287 {
00288     BM_ASSERT(&x != &y);
00289     x ^= y;
00290     y ^= x;
00291     x ^= y;
00292 }
00293 
00294 
00295 //---------------------------------------------------------------------
00296 
00297 /*! 
00298    \brief Lexicographical comparison of two words as bit strings.
00299    Auxiliary implementation for testing and reference purposes.
00300    \param buf1 - First word.
00301    \param buf2 - Second word.
00302    \return  <0 - less, =0 - equal,  >0 - greater.
00303 
00304    @ingroup bitfunc 
00305 */
00306 template<typename T> int wordcmp0(T w1, T w2)
00307 {
00308     while (w1 != w2)
00309     {
00310         int res = (w1 & 1) - (w2 & 1);
00311         if (res != 0) return res;
00312         w1 >>= 1;
00313         w2 >>= 1;
00314     }
00315     return 0;
00316 }
00317 
00318 
00319 /*! 
00320    \brief Lexicographical comparison of two words as bit strings.
00321    Auxiliary implementation for testing and reference purposes.
00322    \param buf1 - First word.
00323    \param buf2 - Second word.
00324    \return  <0 - less, =0 - equal,  >0 - greater.
00325 
00326    @ingroup bitfunc 
00327 */
00328 /*
00329 template<typename T> int wordcmp(T w1, T w2)
00330 {
00331     T diff = w1 ^ w2;
00332     return diff ? ((w1 & diff & (diff ^ (diff - 1)))? 1 : -1) : 0; 
00333 }
00334 */
00335 
00336 template<typename T> int wordcmp(T a, T b)
00337 {
00338     T diff = a ^ b;
00339     return diff? ( (a & diff & -diff)? 1 : -1 ) : 0;
00340 }
00341 
00342 
00343 // Low bit extraction
00344 // x & (x ^ (x-1))
00345 
00346 
00347 /**
00348     Internal structure. Copyright information.
00349 */
00350 template<bool T> struct _copyright
00351 {
00352     static const char _p[];
00353 };
00354 
00355 template<bool T> const char _copyright<T>::_p[] = 
00356     "BitMagic Library. v.3.6.1 (c) 2002-2009 Anatoliy Kuznetsov.";
00357 
00358 
00359 /*! 
00360    \brief Byte orders recognized by the library.
00361 */
00362 enum ByteOrder
00363 {
00364     BigEndian    = 0,
00365     LittleEndian = 1
00366 };
00367 
00368 
00369 /**
00370     Internal structure. Different global settings.
00371 */
00372 template<bool T> struct globals
00373 {
00374     struct bo
00375     {
00376         ByteOrder  _byte_order;
00377 
00378         bo()
00379         {
00380             unsigned x;
00381             unsigned char *s = (unsigned char *)&x;
00382             s[0] = 1;
00383             s[1] = 2;
00384             s[2] = 3;
00385             s[3] = 4;
00386 
00387             if(x == 0x04030201) 
00388             {
00389                 _byte_order = LittleEndian;
00390                 return;
00391             }
00392 
00393             if(x == 0x01020304) 
00394             {
00395                 _byte_order = BigEndian;
00396                 return;
00397             }
00398 
00399             BM_ASSERT(0); // "Invalid Byte Order\n"
00400             _byte_order = LittleEndian;
00401         }
00402     };
00403 
00404     static bo  _bo;
00405 
00406     static ByteOrder byte_order() { return _bo._byte_order; }
00407 
00408 };
00409 
00410 template<bool T> typename globals<T>::bo globals<T>::_bo;
00411 
00412 
00413 
00414 
00415 
00416 
00417 /*
00418    \brief Binary search for the block where bit = pos located.
00419    \param buf - GAP buffer pointer.
00420    \param pos - index of the element.
00421    \param is_set - output. GAP value (0 or 1). 
00422    \return GAP index.
00423    @ingroup gapfunc
00424 */
00425 template<typename T> 
00426 unsigned gap_bfind(const T* buf, unsigned pos, unsigned* is_set)
00427 {
00428     BM_ASSERT(pos < bm::gap_max_bits);
00429     *is_set = (*buf) & 1;
00430 
00431     register unsigned start = 1;
00432     register unsigned end = 1 + ((*buf) >> 3);
00433 
00434     while ( start != end )
00435     {
00436         unsigned curr = (start + end) >> 1;
00437         if ( buf[curr] < pos )
00438             start = curr + 1;
00439         else
00440             end = curr;
00441     }
00442     *is_set ^= ((start-1) & 1);
00443     return start; 
00444 }
00445 
00446 
00447 /*!
00448    \brief Tests if bit = pos is true.
00449    \param buf - GAP buffer pointer.
00450    \param pos - index of the element.
00451    \return true if position is in "1" gap
00452    @ingroup gapfunc
00453 */
00454 template<typename T> unsigned gap_test(const T* buf, unsigned pos)
00455 {
00456     BM_ASSERT(pos < bm::gap_max_bits);
00457 
00458     unsigned start = 1;
00459     unsigned end = 1 + ((*buf) >> 3);
00460 
00461     if (end - start < 10)
00462     {
00463         unsigned sv = *buf & 1;
00464         unsigned sv1= sv ^ 1;
00465         if (buf[1] >= pos) return sv;
00466         if (buf[2] >= pos) return sv1;
00467         if (buf[3] >= pos) return sv;
00468         if (buf[4] >= pos) return sv1;
00469         if (buf[5] >= pos) return sv;
00470         if (buf[6] >= pos) return sv1;
00471         if (buf[7] >= pos) return sv;
00472         if (buf[8] >= pos) return sv1;
00473         if (buf[9] >= pos) return sv;
00474         BM_ASSERT(0);
00475     }
00476     else
00477     while ( start != end )
00478     {
00479         unsigned curr = (start + end) >> 1;
00480         if ( buf[curr] < pos )
00481             start = curr + 1;
00482         else
00483             end = curr;
00484     }
00485     return ((*buf) & 1) ^ ((--start) & 1); 
00486 }
00487 
00488 
00489 /*! For each non-zero block executes supplied function.
00490 */
00491 template<class T, class F> 
00492 void for_each_nzblock(T*** root, unsigned size1, unsigned size2, 
00493                       F& f)
00494 {
00495     unsigned block_idx = 0;
00496     for (unsigned i = 0; i < size1; ++i)
00497     {
00498         T** blk_blk = root[i];
00499 
00500         if (!blk_blk) 
00501         {
00502             f.on_empty_top(i);
00503             block_idx += size2;
00504             continue;
00505         }
00506 
00507         unsigned non_empty_top = 0;
00508         for (unsigned j = 0;j < size2; ++j, ++block_idx)
00509         {
00510             if (blk_blk[j]) 
00511             {
00512                 f(blk_blk[j], block_idx);
00513                 // re-check (blk_blk[j]): could be a mutation
00514                 non_empty_top += (blk_blk[j] != 0);
00515             }
00516             else
00517             {
00518                 f.on_empty_block(block_idx);
00519             }
00520         } // for j
00521         if (non_empty_top == 0)
00522         {
00523             f.on_empty_top(i);
00524         }
00525     }  // for i
00526 }
00527 
00528 /*! For each non-zero block executes supplied function-predicate.
00529     Function returns if function-predicate returns true
00530 */
00531 template<class T, class F> 
00532 bool for_each_nzblock_if(T*** root, unsigned size1, unsigned size2, F& f)
00533 {
00534     unsigned block_idx = 0;
00535     for (unsigned i = 0; i < size1; ++i)
00536     {
00537         T** blk_blk = root[i];
00538 
00539         if (!blk_blk) 
00540         {
00541             block_idx += bm::set_array_size;
00542             continue;
00543         }
00544 
00545         for (unsigned j = 0;j < size2; ++j, ++block_idx)
00546         {
00547             if (blk_blk[j]) 
00548                 if (f(blk_blk[j], block_idx)) return true;
00549         }
00550     }
00551     return false;
00552 }
00553 
00554 /*! For each block executes supplied function.
00555 */
00556 template<class T, class F> 
00557 void for_each_block(T*** root, unsigned size1, unsigned size2, F& f)
00558 {
00559     unsigned block_idx = 0;
00560 
00561     for (unsigned i = 0; i < size1; ++i)
00562     {
00563         T** blk_blk = root[i];
00564 
00565         if (blk_blk)
00566         {
00567             for (unsigned j = 0;j < size2; ++j, ++block_idx)
00568             {
00569                 f(blk_blk[j], block_idx);
00570             }
00571         }
00572         else
00573         {
00574             for (unsigned j = 0;j < size2; ++j, ++block_idx)
00575             {
00576                 f(0, block_idx);
00577             }
00578         }
00579     }  
00580 }
00581 
00582 
00583 
00584 /*! Special BM optimized analog of STL for_each
00585 */
00586 template<class T, class F> F bmfor_each(T first, T last, F f)
00587 {
00588     do
00589     {
00590         f(*first);
00591         ++first;
00592     } while (first < last);
00593     return f;
00594 }
00595 
00596 /*! Computes SUM of all elements of the sequence
00597 */
00598 template<class T> T sum_arr(T* first, T* last)
00599 {
00600     T sum = 0;
00601     while (first < last)
00602     {
00603         sum += *first;
00604         ++first;
00605     }
00606     return sum;
00607 }
00608 
00609 
00610 
00611 /*! 
00612    \brief Calculates number of bits ON in GAP buffer.
00613    \param buf - GAP buffer pointer.
00614    \param dsize - buffer size
00615    \return Number of non-zero bits.
00616    @ingroup gapfunc
00617 */
00618 template<typename T> unsigned gap_bit_count(const T* buf, unsigned dsize=0) 
00619 {
00620     register const T* pcurr = buf;
00621     if (dsize == 0)
00622         dsize = (*pcurr >> 3);
00623 
00624     register const T* pend = pcurr + dsize;
00625 
00626     register unsigned bits_counter = 0;
00627     ++pcurr;
00628 
00629     if (*buf & 1)
00630     {
00631         bits_counter += *pcurr + 1;
00632         ++pcurr;
00633     }
00634     ++pcurr;  // set GAP to 1
00635 
00636     while (pcurr <= pend)
00637     {
00638         bits_counter += *pcurr - *(pcurr-1);
00639         pcurr += 2; // jump to the next positive GAP
00640     } 
00641 
00642     return bits_counter;
00643 }
00644 
00645 
00646 /*!
00647    \brief Counts 1 bits in GAP buffer in the closed [left, right] diapason.
00648    \param buf - GAP buffer pointer.
00649    \param left - leftmost bit index to start from
00650    \param right- rightmost bit index
00651    \return Number of non-zero bits.
00652 */
00653 template<typename T>
00654 unsigned gap_bit_count_range(const T* buf, T left, T right)
00655 {
00656     BM_ASSERT(left <= right);
00657     
00658     const T* pcurr = buf;
00659     const T* pend = pcurr + (*pcurr >> 3);
00660     
00661     unsigned bits_counter = 0;
00662     unsigned is_set;
00663     unsigned start_pos = gap_bfind(buf, left, &is_set);
00664 
00665     pcurr = buf + start_pos;
00666     if (right <= *pcurr) // we are in the target block right now
00667     {
00668         if (is_set)
00669             bits_counter = (right - left + 1);
00670         return bits_counter;
00671     }
00672     if (is_set)
00673         bits_counter += *pcurr - left + 1;
00674 
00675     unsigned prev_gap = *pcurr++;
00676     is_set ^= 1;
00677     while (right > *pcurr)
00678     {
00679         if (is_set)
00680             bits_counter += *pcurr - prev_gap;
00681         if (pcurr == pend) 
00682             return bits_counter;
00683         prev_gap = *pcurr++;
00684         is_set ^= 1;
00685     }
00686     if (is_set)
00687         bits_counter += right - prev_gap;
00688 
00689     return bits_counter;
00690 }
00691 
00692 /*! 
00693     D-GAP block for_each algorithm
00694     
00695     D-Gap Functor is called for each element but last one.
00696     
00697    \param gap_buf - GAP buffer 
00698     
00699 */
00700 template<class T, class Func> 
00701 void for_each_dgap(const T* gap_buf, Func& func)
00702 {
00703     const T* pcurr = gap_buf;
00704     const T* pend = pcurr + (*pcurr >> 3);
00705     ++pcurr;
00706     
00707     T prev = *pcurr;
00708     func(prev + 1); // first element incremented to avoid 0
00709     ++pcurr;
00710     do
00711     {
00712         func(*pcurr - prev); // all others are [N] - [N-1]
00713         prev = *pcurr;
00714     } while (++pcurr < pend);
00715 }
00716 
00717 /** d-Gap copy functor
00718     @internal
00719 */
00720 template<typename T> struct d_copy_func
00721 {
00722     d_copy_func(T* dg_buf) : dgap_buf_(dg_buf) {}
00723     void operator()(T dgap) { *dgap_buf_++ = dgap; }
00724 
00725     T* dgap_buf_;
00726 };
00727 
00728 /*! 
00729    \brief Convert GAP buffer into D-GAP buffer
00730    
00731    Delta GAP representation is DGAP[N] = GAP[N] - GAP[N-1]    
00732    
00733    \param gap_buf - GAP buffer 
00734    \param dgap_buf - Delta-GAP buffer
00735    \param copy_head - flag to copy GAP header
00736    
00737    \internal
00738    
00739    @ingroup gapfunc
00740 */
00741 template<typename T>
00742 T* gap_2_dgap(const T* gap_buf, T* dgap_buf, bool copy_head=true)
00743 {
00744     if (copy_head) // copy GAP header
00745     {
00746         *dgap_buf++ = *gap_buf;
00747     }
00748 
00749     d_copy_func<T> copy_func(dgap_buf);
00750     for_each_dgap<T, d_copy_func<T> >(gap_buf, copy_func);
00751     return copy_func.dgap_buf_;
00752 }
00753 
00754 /*! 
00755    \brief Convert D-GAP buffer into GAP buffer
00756    
00757    GAP representation is GAP[N] = DGAP[N] + DGAP[N-1]    
00758    
00759    \param dgap_buf - Delta-GAP buffer
00760    \param gap_buf  - GAP buffer
00761 
00762    \internal
00763    @ingroup gapfunc
00764 */
00765 template<typename T>
00766 void dgap_2_gap(const T* dgap_buf, T* gap_buf, T gap_header=0)
00767 {
00768     register const T* pcurr = dgap_buf;
00769     unsigned len;    
00770     if (!gap_header) // GAP header is already part of the stream
00771     {
00772         len = *pcurr >> 3;
00773         *gap_buf++ = *pcurr++; // copy GAP header
00774     }
00775     else // GAP header passed as a parameter
00776     {
00777         len = gap_header >> 3;
00778         *gap_buf++ = gap_header; // assign GAP header
00779     }    
00780     --len; // last element is actually not encoded
00781     register const T* pend = pcurr + len;
00782 
00783     *gap_buf = *pcurr++; // copy first element
00784     if (*gap_buf == 0) 
00785         *gap_buf = 65535; // fix +1 overflow
00786     else
00787         *gap_buf = *gap_buf - 1;
00788     
00789     for (++gap_buf; pcurr < pend; ++pcurr)
00790     {
00791         T prev = *(gap_buf-1); // don't remove temp(undef expression!)           
00792         *gap_buf++ = *pcurr + prev;
00793     }
00794     *gap_buf = 65535; // add missing last element  
00795 }
00796 
00797 
00798 /*! 
00799    \brief Lexicographical comparison of GAP buffers.
00800    \param buf1 - First GAP buffer pointer.
00801    \param buf2 - Second GAP buffer pointer.
00802    \return  <0 - less, =0 - equal,  >0 - greater.
00803 
00804    @ingroup gapfunc
00805 */
00806 template<typename T> int gapcmp(const T* buf1, const T* buf2)
00807 {
00808     const T* pcurr1 = buf1;
00809     const T* pend1 = pcurr1 + (*pcurr1 >> 3);
00810     unsigned bitval1 = *buf1 & 1;
00811     ++pcurr1;
00812 
00813     const T* pcurr2 = buf2;
00814     unsigned bitval2 = *buf2 & 1;
00815     ++pcurr2;
00816 
00817     while (pcurr1 <= pend1)
00818     {
00819         if (*pcurr1 == *pcurr2)
00820         {
00821             if (bitval1 != bitval2)
00822             {
00823                 return (bitval1) ? 1 : -1;
00824             }
00825         }
00826         else
00827         {
00828             if (bitval1 == bitval2)
00829             {
00830                 if (bitval1)
00831                 {
00832                     return (*pcurr1 < *pcurr2) ? -1 : 1;
00833                 }
00834                 else
00835                 {
00836                     return (*pcurr1 < *pcurr2) ? 1 : -1;
00837                 }
00838             }
00839             else
00840             {
00841                 return (bitval1) ? 1 : -1;
00842             }
00843         }
00844 
00845         ++pcurr1; ++pcurr2;
00846 
00847         bitval1 ^= 1;
00848         bitval2 ^= 1;
00849     }
00850 
00851     return 0;
00852 }
00853 
00854 
00855 /*!
00856    \brief Abstract operation for GAP buffers. 
00857           Receives functor F as a template argument
00858    \param dest - destination memory buffer.
00859    \param vect1 - operand 1 GAP encoded buffer.
00860    \param vect1_mask - XOR mask for starting bitflag for vector1 
00861    can be 0 or 1 (1 inverts the vector)
00862    \param vect2 - operand 2 GAP encoded buffer.
00863    \param vect2_mask - same as vect1_mask
00864    \param f - operation functor.
00865    \param dlen - destination length after the operation
00866 
00867    \note Internal function.
00868    @internal
00869 
00870    @ingroup gapfunc
00871 */
00872 template<typename T, class F> 
00873 void gap_buff_op(T*         BMRESTRICT dest, 
00874                  const T*   BMRESTRICT vect1,
00875                  unsigned   vect1_mask, 
00876                  const T*   BMRESTRICT vect2,
00877                  unsigned   vect2_mask, 
00878                  F&         f,
00879                  unsigned&  dlen)
00880 {
00881     register const T*  cur1 = vect1;
00882     register const T*  cur2 = vect2;
00883 
00884     unsigned bitval1 = (*cur1++ & 1) ^ vect1_mask;
00885     unsigned bitval2 = (*cur2++ & 1) ^ vect2_mask;
00886     
00887     unsigned bitval = f(bitval1, bitval2);
00888     unsigned bitval_prev = bitval;
00889 
00890     register T* res = dest; 
00891     *res = bitval;
00892     ++res;
00893 
00894     while (1)
00895     {
00896         bitval = f(bitval1, bitval2);
00897 
00898         // Check if GAP value changes and we need to 
00899         // start the next one.
00900         if (bitval != bitval_prev)
00901         {
00902             ++res;
00903             bitval_prev = bitval;
00904         }
00905 
00906         if (*cur1 < *cur2)
00907         {
00908             *res = *cur1;
00909             ++cur1;
00910             bitval1 ^= 1;
00911         }
00912         else // >=
00913         {
00914             *res = *cur2;
00915             if (*cur2 < *cur1)
00916             {
00917                 bitval2 ^= 1;                
00918             }
00919             else  // equal
00920             {
00921                 if (*cur2 == (bm::gap_max_bits - 1))
00922                 {
00923                     break;
00924                 }
00925 
00926                 ++cur1;
00927                 bitval1 ^= 1;
00928                 bitval2 ^= 1;
00929             }
00930             ++cur2;
00931         }
00932 
00933     } // while
00934 
00935     dlen = (unsigned)(res - dest);
00936     *dest = (*dest & 7) + (dlen << 3);
00937 
00938 }
00939 
00940 /*!
00941    \brief Abstract distance test operation for GAP buffers. 
00942           Receives functor F as a template argument
00943    \param vect1 - operand 1 GAP encoded buffer.
00944    \param vect1_mask - XOR mask for starting bitflag for vector1 
00945                        can be 0 or 1 (1 inverts the vector)
00946    \param vect2 - operand 2 GAP encoded buffer.
00947    \param vect2_mask - same as vect1_mask
00948    \param f - operation functor.
00949    \note Internal function.
00950    \return non zero value if operation result returns any 1 bit 
00951 
00952    @ingroup gapfunc
00953 */
00954 template<typename T, class F> 
00955 unsigned gap_buff_any_op(const T*   BMRESTRICT vect1,
00956                          unsigned              vect1_mask, 
00957                          const T*   BMRESTRICT vect2,
00958                          unsigned              vect2_mask, 
00959                          F                     f)
00960 {
00961     register const T*  cur1 = vect1;
00962     register const T*  cur2 = vect2;
00963 
00964     unsigned bitval1 = (*cur1++ & 1) ^ vect1_mask;
00965     unsigned bitval2 = (*cur2++ & 1) ^ vect2_mask;
00966     
00967     unsigned bitval = f(bitval1, bitval2);
00968     if (bitval)
00969         return bitval;
00970     unsigned bitval_prev = bitval;
00971 
00972     while (1)
00973     {
00974         bitval = f(bitval1, bitval2);
00975         if (bitval)
00976             return bitval;
00977 
00978         if (bitval != bitval_prev)
00979             bitval_prev = bitval;
00980 
00981         if (*cur1 < *cur2)
00982         {
00983             ++cur1;
00984             bitval1 ^= 1;
00985         }
00986         else // >=
00987         {
00988             if (*cur2 < *cur1)
00989             {
00990                 bitval2 ^= 1;                
00991             }
00992             else  // equal
00993             {
00994                 if (*cur2 == (bm::gap_max_bits - 1))
00995                 {
00996                     break;
00997                 }
00998 
00999                 ++cur1;
01000                 bitval1 ^= 1;
01001                 bitval2 ^= 1;
01002             }
01003             ++cur2;
01004         }
01005 
01006     } // while
01007 
01008     return 0;
01009 }
01010 
01011 
01012 
01013 /*!
01014    \brief Abstract distance(similarity) operation for GAP buffers. 
01015           Receives functor F as a template argument
01016    \param vect1 - operand 1 GAP encoded buffer.
01017    \param vect2 - operand 2 GAP encoded buffer.
01018    \param f - operation functor.
01019    \note Internal function.
01020 
01021    @ingroup gapfunc
01022 */
01023 /*
01024 template<typename T, class F> 
01025 unsigned gap_buff_count_op(const T*  vect1, const T*  vect2, F f)
01026 {
01027     register const T* cur1 = vect1;
01028     register const T* cur2 = vect2;
01029 
01030     unsigned bitval1 = (*cur1++ & 1);
01031     unsigned bitval2 = (*cur2++ & 1);
01032     unsigned bitval = f(bitval1, bitval2);
01033     unsigned bitval_prev = bitval;
01034 
01035     unsigned count = 0;
01036     T res;
01037     T res_prev;
01038 
01039     while (1)
01040     {
01041         bitval = f(bitval1, bitval2);
01042 
01043         // Check if GAP value changes and we need to 
01044         // start the next one.
01045         if (bitval != bitval_prev)
01046         {
01047             bitval_prev = bitval;
01048         }
01049 
01050         if (*cur1 < *cur2)
01051         {
01052             if (bitval)
01053                 count += *cur1; 
01054             ++cur1;
01055             bitval1 ^= 1;
01056         }
01057         else // >=
01058         {
01059             if (bitval)
01060                 count += *cur2; 
01061             if (*cur2 < *cur1)
01062             {
01063                 bitval2 ^= 1;                
01064             }
01065             else  // equal
01066             {
01067                 if (*cur2 == (bm::gap_max_bits - 1))
01068                 {
01069                     break;
01070                 }
01071 
01072                 ++cur1;
01073                 bitval1 ^= 1;
01074                 bitval2 ^= 1;
01075             }
01076             ++cur2;
01077         }
01078 
01079     } // while
01080 
01081     return count;
01082 }
01083 */
01084 
01085 
01086 /*!
01087    \brief Sets or clears bit in the GAP buffer.
01088 
01089    \param val - new bit value
01090    \param buf - GAP buffer.
01091    \param pos - Index of bit to set.
01092    \param is_set - (OUT) flag if bit was actually set.
01093 
01094    \return New GAP buffer length. 
01095 
01096    @ingroup gapfunc
01097 */
01098 template<typename T> unsigned gap_set_value(unsigned val, 
01099                                             T* BMRESTRICT buf, 
01100                                             unsigned pos, 
01101                                             unsigned* BMRESTRICT is_set)
01102 {
01103     BM_ASSERT(pos < bm::gap_max_bits);
01104     unsigned curr = gap_bfind(buf, pos, is_set);
01105 
01106     register T end = (*buf >> 3);
01107     if (*is_set == val)
01108     {
01109         *is_set = 0;
01110         return end;
01111     }
01112     *is_set = 1;
01113 
01114     register T* pcurr = buf + curr;
01115     register T* pprev = pcurr - 1;
01116     register T* pend = buf + end;
01117 
01118     // Special case, first bit GAP operation. There is no platform beside it.
01119     // initial flag must be inverted.
01120     if (pos == 0)
01121     {
01122         *buf ^= 1;
01123         if ( buf[1] ) // We need to insert a 1 bit platform here.
01124         {
01125             ::memmove(&buf[2], &buf[1], (end - 1) * sizeof(gap_word_t));
01126             buf[1] = 0;
01127             ++end;
01128         }
01129         else // Only 1 bit in the GAP. We need to delete the first GAP.
01130         {
01131             pprev = buf + 1;
01132             pcurr = pprev + 1;
01133             do
01134             {
01135                 *pprev++ = *pcurr++;
01136             } while (pcurr < pend);
01137             --end;
01138         }
01139     }
01140     else if (curr > 1 && ((unsigned)(*pprev))+1 == pos) // Left border bit
01141     {
01142        ++(*pprev);
01143        if (*pprev == *pcurr)  // Curr. GAP to be merged with prev.GAP.
01144        {
01145             --end;
01146             if (pcurr != pend) // GAP merge: 2 GAPS to be deleted 
01147             {
01148                 --end;
01149                 ++pcurr;
01150                 do
01151                 {
01152                     *pprev++ = *pcurr++;
01153                 } while (pcurr < pend);
01154             }
01155        }    
01156     }
01157     else if (*pcurr == pos) // Rightmost bit in the GAP. Border goes left.
01158     {
01159         --(*pcurr);       
01160         if (pcurr == pend)
01161         {
01162            ++end;
01163         }
01164     }
01165     else  // Worst case we need to split current block.
01166     {
01167         ::memmove(pcurr+2, pcurr,(end - curr + 1)*sizeof(T));
01168         *pcurr++ = pos - 1;
01169         *pcurr = pos;
01170         end+=2;
01171     }
01172 
01173     // Set correct length word.
01174     *buf = (*buf & 7) + (end << 3);
01175 
01176     buf[end] = bm::gap_max_bits - 1;
01177     return end;
01178 }
01179 
01180 //------------------------------------------------------------------------
01181 
01182 /**
01183     \brief Searches for the next 1 bit in the GAP block
01184     \param buf - GAP buffer
01185     \param nbit - bit index to start checking from.
01186     \param prev - returns previously checked value
01187 
01188     @ingroup gapfunc
01189 */
01190 template<typename T> int gap_find_in_block(const T* buf, 
01191                                            unsigned nbit, 
01192                                            bm::id_t* prev)
01193 {
01194     BM_ASSERT(nbit < bm::gap_max_bits);
01195 
01196     unsigned bitval;
01197     unsigned gap_idx = bm::gap_bfind(buf, nbit, &bitval);
01198 
01199     if (bitval) // positive block.
01200     {
01201        return 1;
01202     }
01203 
01204     register unsigned val = buf[gap_idx] + 1;
01205     *prev += val - nbit;
01206  
01207     return (val != bm::gap_max_bits);  // no bug here.
01208 }
01209 
01210 /*! 
01211     \brief Set 1 bit in a block
01212     
01213     @ingroup bitfunc
01214 */
01215 BMFORCEINLINE void set_bit(unsigned* dest, unsigned  bitpos)
01216 {
01217     unsigned nbit  = unsigned(bitpos & bm::set_block_mask); 
01218     unsigned nword = unsigned(nbit >> bm::set_word_shift); 
01219     nbit &= bm::set_word_mask;
01220     dest[nword] |= unsigned(1 << nbit);
01221 }
01222 
01223 /*! 
01224     \brief Test 1 bit in a block
01225     
01226     @ingroup bitfunc
01227 */
01228 BMFORCEINLINE unsigned test_bit(const unsigned* block, unsigned  bitpos)
01229 {
01230     unsigned nbit  = unsigned(bitpos & bm::set_block_mask); 
01231     unsigned nword = unsigned(nbit >> bm::set_word_shift); 
01232     nbit &= bm::set_word_mask;
01233     return block[nword] & unsigned(1 << nbit);
01234 }
01235 
01236 
01237 /*! 
01238    \brief Sets bits to 1 in the bitblock.
01239    \param dest - Bitset buffer.
01240    \param bitpos - Offset of the start bit.
01241    \param bitcount - number of bits to set.
01242 
01243    @ingroup bitfunc
01244 */  
01245 inline void or_bit_block(unsigned* dest, 
01246                          unsigned bitpos, 
01247                          unsigned bitcount)
01248 {
01249     unsigned nbit  = unsigned(bitpos & bm::set_block_mask); 
01250     unsigned nword = unsigned(nbit >> bm::set_word_shift); 
01251     nbit &= bm::set_word_mask;
01252 
01253     bm::word_t* word = dest + nword;
01254 
01255     if (bitcount == 1)  // special case (only 1 bit to set)
01256     {
01257         *word |= unsigned(1 << nbit);
01258         return;
01259     }
01260 
01261     if (nbit) // starting position is not aligned
01262     {
01263         unsigned right_margin = nbit + bitcount;
01264 
01265         // here we checking if we setting bits only in the current
01266         // word. Example: 00111000000000000000000000000000 (32 bits word)
01267 
01268         if (right_margin < 32) 
01269         {
01270             unsigned mask = 
01271                 block_set_table<true>::_right[nbit] & 
01272                 block_set_table<true>::_left[right_margin-1];
01273             *word |= mask;
01274             return; // we are done
01275         }
01276         else
01277         {
01278             *word |= block_set_table<true>::_right[nbit];
01279             bitcount -= 32 - nbit;
01280         }
01281         ++word;
01282     }
01283 
01284     // now we are word aligned, lets find out how many words we 
01285     // can now turn ON using loop
01286 
01287     for ( ;bitcount >= 32; bitcount -= 32) 
01288     {
01289         *word++ = 0xffffffff;
01290     }
01291 
01292     if (bitcount) 
01293     {
01294         *word |= block_set_table<true>::_left[bitcount-1];
01295     }
01296 }
01297 
01298 
01299 /*! 
01300    \brief SUB (AND NOT) bit interval to 1 in the bitblock.
01301    \param dest - Bitset buffer.
01302    \param bitpos - Offset of the start bit.
01303    \param bitcount - number of bits to set.
01304 
01305    @ingroup bitfunc
01306 */  
01307 inline void sub_bit_block(unsigned* dest, 
01308                           unsigned bitpos, 
01309                           unsigned bitcount)
01310 {
01311     unsigned nbit  = unsigned(bitpos & bm::set_block_mask); 
01312     unsigned nword = unsigned(nbit >> bm::set_word_shift); 
01313     nbit &= bm::set_word_mask;
01314 
01315     bm::word_t* word = dest + nword;
01316 
01317     if (bitcount == 1)  // special case (only 1 bit to set)
01318     {
01319         *word &= ~unsigned(1 << nbit);
01320         return;
01321     }
01322 
01323     if (nbit) // starting position is not aligned
01324     {
01325         unsigned right_margin = nbit + bitcount;
01326 
01327         // here we checking if we setting bits only in the current
01328         // word. Example: 00111000000000000000000000000000 (32 bits word)
01329 
01330         if (right_margin < 32) 
01331         {
01332             unsigned mask = 
01333                 block_set_table<true>::_right[nbit] & 
01334                 block_set_table<true>::_left[right_margin-1];
01335             *word &= ~mask;
01336             return; // we are done
01337         }
01338         else
01339         {
01340             *word &= ~block_set_table<true>::_right[nbit];
01341             bitcount -= 32 - nbit;
01342         }
01343         ++word;
01344     }
01345 
01346     // now we are word aligned, lets find out how many words we 
01347     // can now turn ON using loop
01348 
01349     for ( ;bitcount >= 32; bitcount -= 32) 
01350     {
01351         *word++ = 0;
01352     }
01353 
01354     if (bitcount) 
01355     {
01356         *word &= ~block_set_table<true>::_left[bitcount-1];
01357     }
01358 }
01359 
01360 
01361 /*! 
01362    \brief XOR bit interval to 1 in the bitblock.
01363    \param dest - Bitset buffer.
01364    \param bitpos - Offset of the start bit.
01365    \param bitcount - number of bits to set.
01366 
01367    @ingroup bitfunc
01368 */  
01369 inline void xor_bit_block(unsigned* dest, 
01370                           unsigned bitpos, 
01371                           unsigned bitcount)
01372 {
01373     unsigned nbit  = unsigned(bitpos & bm::set_block_mask); 
01374     unsigned nword = unsigned(nbit >> bm::set_word_shift); 
01375     nbit &= bm::set_word_mask;
01376 
01377     bm::word_t* word = dest + nword;
01378 
01379     if (bitcount == 1)  // special case (only 1 bit to set)
01380     {
01381         *word ^= unsigned(1 << nbit);
01382         return;                             
01383     }
01384 
01385     if (nbit) // starting position is not aligned
01386     {
01387         unsigned right_margin = nbit + bitcount;
01388 
01389         // here we checking if we setting bits only in the current
01390         // word. Example: 00111000000000000000000000000000 (32 bits word)
01391 
01392         if (right_margin < 32) 
01393         {
01394             unsigned mask = 
01395                 block_set_table<true>::_right[nbit] & 
01396                 block_set_table<true>::_left[right_margin-1];
01397             *word ^= mask;
01398             return; // we are done
01399         }
01400         else
01401         {
01402             *word ^= block_set_table<true>::_right[nbit];
01403             bitcount -= 32 - nbit;
01404         }
01405         ++word;
01406     }
01407 
01408     // now we are word aligned, lets find out how many words we 
01409     // can now turn ON using loop
01410 
01411     for ( ;bitcount >= 32; bitcount -= 32) 
01412     {
01413         *word++ ^= 0xffffffff;
01414     }
01415 
01416     if (bitcount) 
01417     {
01418         *word ^= block_set_table<true>::_left[bitcount-1];
01419     }
01420 }
01421 
01422 
01423 /*!
01424    \brief SUB (AND NOT) GAP block to bitblock.
01425    \param dest - bitblock buffer pointer.
01426    \param buf  - GAP buffer pointer.
01427 
01428    @ingroup gapfunc
01429 */
01430 template<typename T> 
01431 void gap_sub_to_bitset(unsigned* dest, const T*  buf)
01432 {
01433     register const T* pcurr = buf;    
01434     register const T* pend = pcurr + (*pcurr >> 3);
01435     ++pcurr;
01436 
01437     if (*buf & 1)  // Starts with 1
01438     {
01439         sub_bit_block(dest, 0, *pcurr + 1);
01440         ++pcurr;
01441     }
01442     ++pcurr; // now we are in GAP "1" again
01443 
01444     while (pcurr <= pend)
01445     {
01446         unsigned bitpos = *(pcurr-1) + 1;
01447         BM_ASSERT(*pcurr > *(pcurr-1));
01448         unsigned gap_len = *pcurr - *(pcurr-1);
01449         sub_bit_block(dest, bitpos, gap_len);
01450         pcurr += 2;
01451     }
01452 }
01453 
01454 
01455 /*!
01456    \brief XOR GAP block to bitblock.
01457    \param dest - bitblock buffer pointer.
01458    \param buf  - GAP buffer pointer.
01459 
01460    @ingroup gapfunc
01461 */
01462 template<typename T> 
01463 void gap_xor_to_bitset(unsigned* dest, const T*  buf)
01464 {
01465     register const T* pcurr = buf;    
01466     register const T* pend = pcurr + (*pcurr >> 3);
01467     ++pcurr;
01468 
01469     if (*buf & 1)  // Starts with 1
01470     {
01471         xor_bit_block(dest, 0, *pcurr + 1);
01472         ++pcurr;
01473     }
01474     ++pcurr; // now we are in GAP "1" again
01475 
01476     while (pcurr <= pend)
01477     {
01478         unsigned bitpos = *(pcurr-1) + 1;
01479         BM_ASSERT(*pcurr > *(pcurr-1));
01480         unsigned gap_len = *pcurr - *(pcurr-1);
01481         xor_bit_block(dest, bitpos, gap_len);
01482         pcurr += 2;
01483     }
01484 }
01485 
01486 
01487 /*!
01488    \brief Adds(OR) GAP block to bitblock.
01489    \param dest - bitblock buffer pointer.
01490    \param buf  - GAP buffer pointer.
01491 
01492    @ingroup gapfunc
01493 */
01494 template<typename T> 
01495 void gap_add_to_bitset(unsigned* dest, const T*  buf)
01496 {
01497     register const T* pcurr = buf;    
01498     register const T* pend = pcurr + (*pcurr >> 3);
01499     ++pcurr;
01500 
01501     if (*buf & 1)  // Starts with 1
01502     {
01503         or_bit_block(dest, 0, *pcurr + 1);
01504         ++pcurr;
01505     }
01506     ++pcurr; // now we are in GAP "1" again
01507 
01508     while (pcurr <= pend)
01509     {
01510         unsigned bitpos = *(pcurr-1) + 1;
01511         BM_ASSERT(*pcurr > *(pcurr-1));
01512         unsigned gap_len = *pcurr - *(pcurr-1);
01513         or_bit_block(dest, bitpos, gap_len);
01514         pcurr += 2;
01515     }
01516 }
01517 
01518 
01519 /*!
01520    \brief ANDs GAP block to bitblock.
01521    \param dest - bitblock buffer pointer.
01522    \param buf  - GAP buffer pointer.
01523 
01524    @ingroup gapfunc
01525 */
01526 template<typename T> 
01527 void gap_and_to_bitset(unsigned* dest, const T*  buf)
01528 {
01529     register const T* pcurr = buf;    
01530     register const T* pend = pcurr + (*pcurr >> 3);
01531     ++pcurr;
01532 
01533     if (! (*buf & 1) )  // Starts with 0 
01534     {
01535         // Instead of AND we can SUB 0 gaps here 
01536         sub_bit_block(dest, 0, *pcurr + 1);
01537         ++pcurr;
01538     }
01539     ++pcurr; // now we are in GAP "0" again
01540 
01541     while (pcurr <= pend)
01542     {
01543         unsigned bitpos = *(pcurr-1) + 1;
01544         BM_ASSERT(*pcurr > *(pcurr-1));
01545         unsigned gap_len = *pcurr - *(pcurr-1);
01546         sub_bit_block(dest, bitpos, gap_len);
01547         pcurr += 2;
01548     }
01549 }
01550 
01551 
01552 /*!
01553    \brief Compute bitcount of bit block AND masked by GAP block.
01554    \param dest - bitblock buffer pointer.
01555    \param buf  - GAP buffer pointer.
01556 
01557    @ingroup gapfunc bitfunc
01558 */
01559 template<typename T> 
01560 bm::id_t gap_bitset_and_count(const unsigned* block, const T*  buf)
01561 {
01562     BM_ASSERT(block);
01563 
01564     register const T* pcurr = buf;    
01565     register const T* pend = pcurr + (*pcurr >> 3);
01566     ++pcurr;
01567 
01568     bm::id_t count = 0;
01569 
01570     if (*buf & 1)  // Starts with 1
01571     {
01572         count += bit_block_calc_count_range(block, 0, *pcurr);
01573         ++pcurr;
01574     }
01575     ++pcurr; // now we are in GAP "1" again
01576 
01577     while (pcurr <= pend)
01578     {
01579         bm::id_t c = bit_block_calc_count_range(block, *(pcurr-1)+1, *pcurr);
01580 
01581         count += c;
01582         pcurr += 2;
01583     }
01584     return count;
01585 }
01586 
01587 
01588 /*!
01589    \brief Bitcount test of bit block AND masked by GAP block.
01590    \param dest - bitblock buffer pointer.
01591    \param buf  - GAP buffer pointer.
01592 
01593    @ingroup gapfunc bitfunc
01594 */
01595 template<typename T> 
01596 bm::id_t gap_bitset_and_any(const unsigned* block, const T*  buf)
01597 {
01598     BM_ASSERT(block);
01599 
01600     register const T* pcurr = buf;    
01601     register const T* pend = pcurr + (*pcurr >> 3);
01602     ++pcurr;
01603 
01604     bm::id_t count = 0;
01605     if (*buf & 1)  // Starts with 1
01606     {
01607         count += bit_block_any_range(block, 0, *pcurr);
01608         if (count)
01609             return count;
01610         ++pcurr;
01611     }
01612     ++pcurr; // now we are in GAP "1" again
01613 
01614     while (pcurr <= pend)
01615     {
01616         bm::id_t c = bit_block_any_range(block, *(pcurr-1)+1, *pcurr);
01617         count += c;
01618         if (count)
01619             break;
01620         pcurr += 2;
01621     }
01622     return count;
01623 }
01624 
01625 
01626 
01627 /*!
01628    \brief Compute bitcount of bit block SUB masked by GAP block.
01629    \param dest - bitblock buffer pointer.
01630    \param buf  - GAP buffer pointer.
01631 
01632    @ingroup gapfunc bitfunc
01633 */
01634 template<typename T> 
01635 bm::id_t gap_bitset_sub_count(const unsigned* block, const T*  buf)
01636 {
01637     BM_ASSERT(block);
01638 
01639     register const T* pcurr = buf;    
01640     register const T* pend = pcurr + (*pcurr >> 3);
01641     ++pcurr;
01642 
01643     bm::id_t count = 0;
01644 
01645     if (!(*buf & 1))  // Starts with 0
01646     {
01647         count += bit_block_calc_count_range(block, 0, *pcurr);
01648         ++pcurr;
01649     }
01650     ++pcurr; // now we are in GAP "0" again
01651 
01652     for (;pcurr <= pend; pcurr+=2)
01653     {
01654         count += bit_block_calc_count_range(block, *(pcurr-1)+1, *pcurr);
01655     }
01656     return count;
01657 }
01658 
01659 
01660 /*!
01661    \brief Compute bitcount test of bit block SUB masked by GAP block.
01662    \param dest - bitblock buffer pointer.
01663    \param buf  - GAP buffer pointer.
01664 
01665    @ingroup gapfunc bitfunc
01666 */
01667 template<typename T> 
01668 bm::id_t gap_bitset_sub_any(const unsigned* block, const T*  buf)
01669 {
01670     BM_ASSERT(block);
01671 
01672     register const T* pcurr = buf;    
01673     register const T* pend = pcurr + (*pcurr >> 3);
01674     ++pcurr;
01675 
01676     bm::id_t count = 0;
01677 
01678     if (!(*buf & 1))  // Starts with 0
01679     {
01680         count += bit_block_any_range(block, 0, *pcurr);
01681         if (count)
01682             return count;
01683         ++pcurr;
01684     }
01685     ++pcurr; // now we are in GAP "0" again
01686 
01687     for (;pcurr <= pend; pcurr+=2)
01688     {
01689         count += bit_block_any_range(block, *(pcurr-1)+1, *pcurr);
01690         if (count)
01691             return count;
01692     }
01693     return count;
01694 }
01695 
01696 
01697 
01698 /*!
01699    \brief Compute bitcount of bit block XOR masked by GAP block.
01700    \param dest - bitblock buffer pointer.
01701    \param buf  - GAP buffer pointer.
01702 
01703    @ingroup gapfunc bitfunc
01704 */
01705 template<typename T> 
01706 bm::id_t gap_bitset_xor_count(const unsigned* block, const T*  buf)
01707 {
01708     BM_ASSERT(block);
01709 
01710     register const T* pcurr = buf;    
01711     register const T* pend = pcurr + (*pcurr >> 3);
01712     ++pcurr;
01713 
01714     unsigned bitval = *buf & 1;
01715     
01716     register bm::id_t count = bit_block_calc_count_range(block, 0, *pcurr);
01717     if (bitval)
01718     {
01719         count = *pcurr + 1 - count;
01720     }
01721     
01722     for (bitval^=1, ++pcurr; pcurr <= pend; bitval^=1, ++pcurr)
01723     {
01724         T prev = *(pcurr-1)+1;
01725         bm::id_t c = bit_block_calc_count_range(block, prev, *pcurr);
01726         
01727         if (bitval) // 1 gap; means Result = Total_Bits - BitCount;
01728         {
01729             c = (*pcurr - prev + 1) - c;
01730         }
01731         count += c;
01732     }
01733     return count;
01734 }
01735 
01736 /*!
01737    \brief Compute bitcount test of bit block XOR masked by GAP block.
01738    \param dest - bitblock buffer pointer.
01739    \param buf  - GAP buffer pointer.
01740 
01741    @ingroup gapfunc bitfunc
01742 */
01743 template<typename T> 
01744 bm::id_t gap_bitset_xor_any(const unsigned* block, const T*  buf)
01745 {
01746     BM_ASSERT(block);
01747 
01748     register const T* pcurr = buf;    
01749     register const T* pend = pcurr + (*pcurr >> 3);
01750     ++pcurr;
01751 
01752     unsigned bitval = *buf & 1;
01753     
01754     register bm::id_t count = bit_block_any_range(block, 0, *pcurr);
01755     if (bitval)
01756     {
01757         count = *pcurr + 1 - count;
01758     }
01759     
01760     for (bitval^=1, ++pcurr; pcurr <= pend; bitval^=1, ++pcurr)
01761     {
01762         T prev = *(pcurr-1)+1;
01763         bm::id_t c = bit_block_any_range(block, prev, *pcurr);
01764         
01765         if (bitval) // 1 gap; means Result = Total_Bits - BitCount;
01766         {
01767             c = (*pcurr - prev + 1) - c;
01768         }
01769         
01770         count += c;
01771         if (count)
01772             return count;
01773     }
01774     return count;
01775 }
01776 
01777 
01778 
01779 /*!
01780    \brief Compute bitcount of bit block OR masked by GAP block.
01781    \param dest - bitblock buffer pointer.
01782    \param buf  - GAP buffer pointer.
01783 
01784    @ingroup gapfunc bitfunc
01785 */
01786 template<typename T> 
01787 bm::id_t gap_bitset_or_count(const unsigned* block, const T*  buf)
01788 {
01789     BM_ASSERT(block);
01790 
01791     register const T* pcurr = buf;    
01792     register const T* pend = pcurr + (*pcurr >> 3);
01793     ++pcurr;
01794 
01795     unsigned bitval = *buf & 1;
01796     
01797     register bm::id_t count;
01798     if (bitval)
01799     {
01800         count = *pcurr + 1;
01801     } 
01802     else
01803     {
01804         count = bit_block_calc_count_range(block, 0, *pcurr);
01805     }
01806     
01807     for (bitval^=1, ++pcurr; pcurr <= pend; bitval^=1, ++pcurr)
01808     {
01809         T prev = *(pcurr-1)+1;
01810         bm::id_t c;
01811         
01812         if (bitval)
01813         {
01814             c = (*pcurr - prev + 1);
01815         }
01816         else
01817         {
01818             c = bit_block_calc_count_range(block, prev, *pcurr);
01819         }
01820         
01821         count += c;
01822     }
01823     return count;
01824 }
01825 
01826 /*!
01827    \brief Compute bitcount test of bit block OR masked by GAP block.
01828    \param dest - bitblock buffer pointer.
01829    \param buf  - GAP buffer pointer.
01830 
01831    @ingroup gapfunc bitfunc
01832 */
01833 template<typename T> 
01834 bm::id_t gap_bitset_or_any(const unsigned* block, const T*  buf)
01835 {
01836     BM_ASSERT(block);
01837 
01838     register const T* pcurr = buf;    
01839     register const T* pend = pcurr + (*pcurr >> 3);
01840     ++pcurr;
01841 
01842     unsigned bitval = *buf & 1;
01843     
01844     register bm::id_t count;
01845     if (bitval)
01846     {
01847         count = *pcurr + 1;
01848     } 
01849     else
01850     {
01851         count = bit_block_any_range(block, 0, *pcurr);
01852     }
01853     
01854     for (bitval^=1, ++pcurr; pcurr <= pend; bitval^=1, ++pcurr)
01855     {
01856         T prev = *(pcurr-1)+1;
01857         bm::id_t c;
01858         
01859         if (bitval)
01860         {
01861             c = (*pcurr - prev + 1);
01862         }
01863         else
01864         {
01865             c = bit_block_any_range(block, prev, *pcurr);
01866         }        
01867         count += c;
01868         if (count)
01869             return count;
01870     }
01871     return count;
01872 }
01873 
01874 
01875 
01876 /*!
01877    \brief Bitblock memset operation. 
01878 
01879    \param dst - destination block.
01880    \param value - value to set.
01881 
01882    @ingroup bitfunc
01883 */
01884 inline 
01885 void bit_block_set(bm::word_t* BMRESTRICT dst, bm::word_t value)
01886 {
01887 //#ifdef BMVECTOPT
01888 //    VECT_SET_BLOCK(dst, dst + bm::set_block_size, value);
01889 //#else
01890     ::memset(dst, value, bm::set_block_size * sizeof(bm::word_t));
01891 //#endif
01892 }
01893 
01894 
01895 /*!
01896    \brief GAP block to bitblock conversion.
01897    \param dest - bitblock buffer pointer.
01898    \param buf  - GAP buffer pointer.
01899 
01900    @ingroup gapfunc
01901 */
01902 template<typename T> 
01903 void gap_convert_to_bitset(unsigned* dest, const T*  buf)
01904 {
01905     bit_block_set(dest, 0);
01906     gap_add_to_bitset(dest, buf);
01907 }
01908 
01909 
01910 /*!
01911    \brief GAP block to bitblock conversion.
01912    \param dest - bitblock buffer pointer.
01913    \param buf  - GAP buffer pointer.
01914    \param dest_size - length of the destination buffer.
01915 
01916    @ingroup gapfunc
01917 */
01918 template<typename T> 
01919 void gap_convert_to_bitset(unsigned* dest, const T*  buf,  unsigned  dest_len)
01920 {
01921    ::memset(dest, 0, dest_len * sizeof(unsigned));
01922     gap_add_to_bitset(dest, buf);
01923 }
01924 
01925 
01926 
01927 /*!
01928    \brief Smart GAP block to bitblock conversion.
01929 
01930     Checks if GAP block is ALL-ZERO or ALL-ON. In those cases returns 
01931     pointer on special static bitblocks.
01932 
01933    \param dest - bitblock buffer pointer.
01934    \param buf  - GAP buffer pointer.
01935    \param set_max - max possible bitset length
01936 
01937    @ingroup gapfunc
01938 */
01939 template<typename T> 
01940         unsigned* gap_convert_to_bitset_smart(unsigned* dest,
01941                                               const T* buf, 
01942                                               id_t set_max)
01943 {
01944     if (buf[1] == set_max - 1)
01945     {
01946         return (buf[0] & 1) ? FULL_BLOCK_ADDR : 0;
01947     }
01948 
01949     gap_convert_to_bitset(dest, buf);
01950     return dest;
01951 }
01952 
01953 
01954 /*!
01955    \brief Calculates sum of all words in GAP block. (For debugging purposes)
01956    \note For debugging and testing ONLY.
01957    \param buf - GAP buffer pointer.
01958    \return Sum of all words.
01959 
01960    @ingroup gapfunc
01961 */
01962 template<typename T> unsigned gap_control_sum(const T* buf)
01963 {
01964     unsigned end = *buf >> 3;
01965 
01966     register const T* pcurr = buf;    
01967     register const T* pend = pcurr + (*pcurr >> 3);
01968     ++pcurr;
01969 
01970     if (*buf & 1)  // Starts with 1
01971     {
01972         ++pcurr;
01973     }
01974     ++pcurr; // now we are in GAP "1" again
01975 
01976     while (pcurr <= pend)
01977     {
01978         BM_ASSERT(*pcurr > *(pcurr-1));
01979         pcurr += 2;
01980     }
01981     return buf[end];
01982 
01983 }
01984 
01985 
01986 /*! 
01987    \brief Sets all bits to 0 or 1 (GAP)
01988    \param buf - GAP buffer pointer.
01989    \param set_max - max possible bitset length
01990 
01991    @ingroup gapfunc
01992 */
01993 template<class T> void gap_set_all(T* buf, 
01994                                         unsigned set_max,
01995                                         unsigned value)
01996 {
01997     BM_ASSERT(value == 0 || value == 1);
01998     *buf = (*buf & 6u) + (1u << 3) + value;
01999     *(++buf) = set_max - 1;
02000 }
02001 
02002 
02003 /*!
02004     \brief Init gap block so it has block in it (can be whole block)
02005     \param buf  - GAP buffer pointer.
02006     \param from - one block start
02007     \param to   - one block end
02008     \param value - (block value)1 or 0
02009     \param set_max - max possible bitset length
02010     
02011    @ingroup gapfunc
02012 */
02013 template<class T> 
02014 void gap_init_range_block(T*       buf,
02015                           unsigned from,
02016                           unsigned to,
02017                           unsigned value,
02018                           unsigned set_max)
02019 {
02020     BM_ASSERT(value == 0 || value == 1);
02021 
02022     unsigned gap_len;
02023     if (from == 0)
02024     {
02025         if (to == set_max - 1)
02026         {
02027             gap_set_all(buf, set_max, value);
02028         }
02029         else
02030         {
02031             gap_len = 2;
02032             buf[1] = to;
02033             buf[2] = set_max - 1;
02034             buf[0] =  (*buf & 6u) + (gap_len << 3) + value;
02035         }
02036         return;
02037     }
02038     // from != 0
02039 
02040     value = !value;
02041     if (to == set_max - 1)
02042     {
02043         gap_len = 2;
02044         buf[1] = from - 1;
02045         buf[2] = set_max - 1;
02046     }
02047     else
02048     {
02049         gap_len = 3;
02050         buf[1] = from - 1;
02051         buf[2] = to;
02052         buf[3] = set_max - 1;
02053     }
02054     buf[0] =  (*buf & 6u) + (gap_len << 3) + value;
02055 }
02056 
02057 
02058 /*! 
02059    \brief Inverts all bits in the GAP buffer.
02060    \param buf - GAP buffer pointer.
02061 
02062    @ingroup gapfunc
02063 */
02064 template<typename T> void gap_invert(T* buf)
02065 { 
02066     *buf ^= 1;
02067 }
02068 
02069 /*! 
02070    \brief Temporary inverts all bits in the GAP buffer.
02071    
02072    In this function const-ness of the buffer means nothing.
02073    Calling this function again restores the status of the buffer.
02074 
02075    \param buf - GAP buffer pointer. (Buffer IS changed) 
02076 
02077    @ingroup gapfunc
02078 */
02079 /*
02080 template<typename T> void gap_temp_invert(const T* buf)
02081 {
02082     T* buftmp = const_cast<T*>(buf);
02083     *buftmp ^= 1;
02084 }
02085 */
02086 
02087 /*!
02088    \brief Checks if GAP block is all-zero.
02089    \param buf - GAP buffer pointer.
02090    \param set_max - max possible bitset length
02091    \returns true if all-zero.
02092 
02093    @ingroup gapfunc
02094 */
02095 template<typename T> 
02096              bool gap_is_all_zero(const T* buf, unsigned set_max)
02097 {
02098     return (((*buf & 1)==0)  && (*(++buf) == set_max - 1));
02099 }
02100 
02101 /*!
02102    \brief Checks if GAP block is all-one.
02103    \param buf - GAP buffer pointer.
02104    \param set_max - max possible bitset length
02105    \returns true if all-one.
02106 
02107    @ingroup gapfunc
02108 */
02109 template<typename T> 
02110          bool gap_is_all_one(const T* buf, unsigned set_max)
02111 {
02112     return ((*buf & 1)  && (*(++buf) == set_max - 1));
02113 }
02114 
02115 /*!
02116    \brief Returs GAP block length.
02117    \param buf - GAP buffer pointer.
02118    \returns GAP block length.
02119 
02120    @ingroup gapfunc
02121 */
02122 template<typename T> unsigned gap_length(const T* buf)
02123 {
02124     return (*buf >> 3) + 1;
02125 }
02126 
02127 
02128 /*!
02129    \brief Returs GAP block capacity.
02130    \param buf - GAP buffer pointer.
02131    \returns GAP block capacity.
02132 
02133    @ingroup gapfunc
02134 */
02135 template<typename T> 
02136 unsigned gap_capacity(const T* buf, const T* glevel_len)
02137 {
02138     return glevel_len[(*buf >> 1) & 3];
02139 }
02140 
02141 
02142 /*!
02143    \brief Returs GAP block capacity limit.
02144    \param buf - GAP buffer pointer.
02145    \param glevel_len - GAP lengths table (gap_len_table)
02146    \returns GAP block limit.
02147 
02148    @ingroup gapfunc
02149 */
02150 template<typename T> 
02151 unsigned gap_limit(const T* buf, const T* glevel_len)
02152 {
02153     return glevel_len[(*buf >> 1) & 3]-4;
02154 }
02155 
02156 
02157 /*!
02158    \brief Returs GAP blocks capacity level.
02159    \param buf - GAP buffer pointer.
02160    \returns GAP block capacity level.
02161 
02162    @ingroup gapfunc
02163 */
02164 template<typename T> unsigned gap_level(const T* buf)
02165 {
02166     return (*buf >> 1) & 3;
02167 }
02168 
02169 
02170 /*!
02171    \brief Sets GAP block capacity level.
02172    \param buf - GAP buffer pointer.
02173    \param level new GAP block capacity level.
02174 
02175    @ingroup gapfunc
02176 */
02177 template<typename T> void set_gap_level(T* buf, 
02178                                         unsigned level)
02179 {
02180     BM_ASSERT(level < bm::gap_levels);
02181     *buf = ((level & 3) << 1) | (*buf & 1) | (*buf & ~7); 
02182 }
02183 
02184 
02185 /*!
02186    \brief Calculates GAP block capacity level.
02187    \param len - GAP buffer length.
02188    \param glevel_len - GAP lengths table
02189    \return GAP block capacity level. 
02190             -1 if block does not fit any level.
02191    @ingroup gapfunc
02192 */
02193 template<typename T>
02194 inline int gap_calc_level(int len, const T* glevel_len)
02195 {
02196     if (len <= (glevel_len[0]-4)) return 0;
02197     if (len <= (glevel_len[1]-4)) return 1;
02198     if (len <= (glevel_len[2]-4)) return 2;
02199     if (len <= (glevel_len[3]-4)) return 3;
02200 
02201     BM_ASSERT(bm::gap_levels == 4);
02202     return -1;
02203 }
02204 
02205 /*! @brief Returns number of free elements in GAP block array. 
02206     Difference between GAP block capacity on this level and actual GAP length.
02207     
02208     @param buf - GAP buffer pointer
02209     @parma glevel_len - GAP lengths table
02210     
02211     @return Number of free GAP elements
02212     @ingroup gapfunc
02213 */
02214 template<typename T>
02215 inline unsigned gap_free_elements(const T* buf, const T* glevel_len)
02216 {
02217     unsigned len = gap_length(buf);
02218     unsigned capacity = gap_capacity(buf, glevel_len);
02219     return capacity - len;
02220 }
02221 
02222 
02223 /*! 
02224    \brief Lexicographical comparison of BIT buffers.
02225    \param buf1 - First buffer pointer.
02226    \param buf2 - Second buffer pointer.
02227    \param len - Buffer length in elements (T).
02228    \return  <0 - less, =0 - equal,  >0 - greater.
02229 
02230    @ingroup bitfunc 
02231 */
02232 template<typename T> 
02233 int bitcmp(const T* buf1, const T* buf2, unsigned len)
02234 {
02235     BM_ASSERT(len);
02236     const T* pend1 = buf1 + len; 
02237     do
02238     {
02239         T w1 = *buf1++;
02240         T w2 = *buf2++;
02241         T diff = w1 ^ w2;
02242     
02243         if (diff)
02244         { 
02245             return (w1 & diff & -diff) ? 1 : -1;
02246         }
02247 
02248     } while (buf1 < pend1);
02249 
02250     return 0;
02251 }
02252 
02253 
02254 /*! 
02255    \brief Converts bit block to GAP. 
02256    \param dest - Destinatio GAP buffer.
02257    \param src - Source bitblock buffer.
02258    \param bits - Number of bits to convert.
02259    \param dest_len - length of the dest. buffer.
02260    \return  New length of GAP block or 0 if conversion failed 
02261    (insufficicent space).
02262 
02263    @ingroup gapfunc
02264 */
02265 template<typename T> 
02266     unsigned bit_convert_to_gap(T* BMRESTRICT dest, 
02267                                 const unsigned* BMRESTRICT src, 
02268                                 bm::id_t bits, 
02269                                 unsigned dest_len)
02270 {
02271     register T* BMRESTRICT pcurr = dest;
02272     T* BMRESTRICT end = dest + dest_len; 
02273     register int bitval = (*src) & 1;
02274 //    *pcurr |= bitval;
02275     *pcurr = bitval;
02276 
02277     ++pcurr;
02278     *pcurr = 0;
02279     register unsigned bit_idx = 0;
02280     register int bitval_next;
02281 
02282     unsigned val = *src;
02283 
02284     do
02285     {
02286         // We can fast pace if *src == 0 or *src = 0xffffffff
02287 
02288         while (val == 0 || val == 0xffffffff)
02289         {
02290            bitval_next = val ? 1 : 0;
02291            if (bitval != bitval_next)
02292            {
02293                *pcurr++ = bit_idx-1; 
02294                BM_ASSERT((pcurr-1) == (dest+1) || *(pcurr-1) > *(pcurr-2));
02295                if (pcurr >= end)
02296                {
02297                    return 0; // OUT of memory
02298                }
02299                bitval = bitval_next;
02300            }
02301            bit_idx += sizeof(*src) * 8;
02302            if (bit_idx >= bits)
02303            {
02304                goto complete;
02305            }
02306            ++src;
02307            val = *src;
02308         }
02309 
02310 
02311         register unsigned mask = 1;
02312         while (mask)
02313         {
02314             // Now plain bitshifting. TODO: Optimization wanted.
02315 
02316             bitval_next = val & mask ? 1 : 0;
02317             if (bitval != bitval_next)
02318             {
02319                 *pcurr++ = bit_idx-1;
02320                 BM_ASSERT((pcurr-1) == (dest+1) || *(pcurr-1) > *(pcurr-2));
02321                 bitval = bitval_next;
02322                 if (pcurr >= end)
02323                 {
02324                     return 0; // OUT of memory
02325                 }
02326             }
02327 
02328             mask <<= 1;
02329             ++bit_idx;
02330 
02331         } // while mask
02332 
02333         if (bit_idx >= bits)
02334         {
02335             goto complete;
02336         }
02337 
02338         ++src;
02339         val = *src;
02340 
02341     } while(1);
02342 
02343 complete:
02344     *pcurr = bit_idx-1;
02345     unsigned len = (unsigned)(pcurr - dest);
02346     *dest = (*dest & 7) + (len << 3);
02347     return len;
02348 }
02349 
02350 
02351 /*!
02352    \brief Iterate gap block as delta-bits with a functor 
02353    @ingroup gapfunc
02354 */
02355 template<class T, class F>
02356 void for_each_gap_dbit(const T* buf, F& func)
02357 {
02358     const T* pcurr = buf;
02359     const T* pend = pcurr + (*pcurr >> 3);
02360 
02361     ++pcurr;
02362 
02363     unsigned prev = 0;
02364     unsigned first_inc;
02365 
02366     if (*buf & 1)
02367     {
02368         first_inc = 0;
02369         unsigned to = *pcurr;
02370         for (unsigned i = 0; i <= to; ++i) 
02371         {
02372             func(1);
02373         }
02374         prev = to;
02375         ++pcurr;
02376     }
02377     else
02378     {
02379         first_inc = 1;
02380     }
02381     ++pcurr;  // set GAP to 1
02382 
02383     while (pcurr <= pend)
02384     {
02385         unsigned from = *(pcurr-1)+1;
02386         unsigned to = *pcurr;
02387         if (first_inc)
02388         {
02389             func(from - prev + first_inc);
02390             first_inc = 0;
02391         }
02392         else
02393         {
02394             func(from - prev);
02395         }
02396 
02397         for (unsigned i = from+1; i <= to; ++i) 
02398         {
02399             func(1);
02400         }
02401         prev = to;
02402         pcurr += 2; // jump to the next positive GAP
02403     }
02404 }
02405 
02406 /*!
02407    \brief Convert gap block into array of ints corresponding to 1 bits
02408    @ingroup gapfunc
02409 */
02410 template<typename D, typename T>
02411 D gap_convert_to_arr(D* BMRESTRICT       dest, 
02412                      const T* BMRESTRICT buf,
02413                      unsigned            dest_len,
02414                      bool                invert = false)
02415 {
02416     register const T* BMRESTRICT pcurr = buf;
02417     register const T* pend = pcurr + (*pcurr >> 3);
02418 
02419     D* BMRESTRICT dest_curr = dest;
02420     ++pcurr;
02421 
02422     int bitval = (*buf) & 1;
02423     if (invert) 
02424         bitval = !bitval; // invert the GAP buffer
02425 
02426     if (bitval)
02427     {
02428         if (unsigned(*pcurr + 1) >= dest_len)
02429             return 0; // insufficient space
02430         dest_len -= *pcurr;
02431         T to = *pcurr;
02432         for (T i = 0; ;++i) 
02433         {
02434             *dest_curr++ = i;
02435             if (i == to) break;
02436         }
02437         ++pcurr;
02438     }
02439     ++pcurr;  // set GAP to 1
02440 
02441     while (pcurr <= pend)
02442     {
02443         unsigned pending = *pcurr - *(pcurr-1);
02444         if (pending >= dest_len)
02445             return 0;
02446         dest_len -= pending;
02447         T from = *(pcurr-1)+1;
02448         T to = *pcurr;
02449         for (T i = from; ;++i) 
02450         {
02451             *dest_curr++ = i;
02452             if (i == to) break;
02453         }
02454         pcurr += 2; // jump to the next positive GAP
02455     }
02456     return (D) (dest_curr - dest);
02457 }
02458 
02459 
02460 
02461 /*! 
02462     @brief Bitcount for bit string
02463     
02464     Function calculates number of 1 bits in the given array of words.
02465     Make sure the addresses are aligned.
02466 
02467     @ingroup bitfunc 
02468 */
02469 inline 
02470 bm::id_t bit_block_calc_count(const bm::word_t* block, 
02471                               const bm::word_t* block_end)
02472 {
02473     BM_ASSERT(block < block_end);
02474     bm::id_t count = 0;
02475 
02476 #ifdef BM64OPT
02477 
02478     // 64-bit optimized algorithm.
02479 
02480     const bm::id64_t* b1 = (bm::id64_t*) block;
02481     const bm::id64_t* b2 = (bm::id64_t*) block_end;
02482 
02483     bm::id64_t  acc = *b1++;  // accumulator (sparse vectors optimization)
02484 
02485     do
02486     {
02487         bm::id64_t in = *b1++;
02488         bm::id64_t acc_prev = acc;
02489         acc |= in;
02490 
02491         if (acc_prev &= in)  // counting bits in accumulator
02492         {
02493             acc = (acc & 0x5555555555555555LU) + (acc >> 1 & 0x5555555555555555LU);
02494             acc = (acc & 0x3333333333333333LU) + (acc >> 2 & 0x3333333333333333LU);
02495             acc = acc + (acc >> 4) & 0x0F0F0F0F0F0F0F0FLU;
02496             acc = acc + (acc >> 8);
02497             acc = acc + (acc >> 16);
02498             acc = acc + (acc >> 32) & 0x0000007F;
02499             count += (unsigned)acc;
02500 
02501             acc = acc_prev;
02502         }
02503     } while (b1 < b2);
02504     count += word_bitcount64(acc);  // count-in remaining accumulator 
02505 
02506 #else
02507     // For 32 bit code the fastest method is
02508     // to use bitcount table for each byte in the block.
02509     // As optimization for sparse bitsets used bits accumulator
02510     // to collect ON bits using bitwise OR. 
02511     bm::word_t  acc = *block++;
02512     do
02513     {
02514         bm::word_t in = *block++;
02515         bm::word_t acc_prev = acc;
02516         acc |= in;
02517         if (acc_prev &= in)  // accumulator miss: counting bits
02518         {
02519             BM_INCWORD_BITCOUNT(count, acc);
02520             acc = acc_prev;
02521         }
02522     } while (block < block_end);
02523 
02524     BM_INCWORD_BITCOUNT(count, acc); // count-in remaining accumulator 
02525 
02526 #endif
02527     
02528     return count;
02529 }
02530 
02531 
02532 
02533 /*!
02534     Function calculates number of times when bit value changed 
02535     (1-0 or 0-1).
02536     
02537     For 001 result is 2
02538         010 - 3
02539         011 - 2
02540         111 - 1
02541     
02542     @ingroup bitfunc 
02543 */
02544 
02545 inline 
02546 bm::id_t bit_count_change(bm::word_t w)
02547 {
02548     unsigned count = 1;
02549     w ^= (w >> 1);
02550 
02551     BM_INCWORD_BITCOUNT(count, w);
02552     count -= (w >> ((sizeof(w) * 8) - 1));
02553     return count;
02554 }
02555 
02556 
02557 /*!
02558     Function calculates number of times when bit value changed 
02559     (1-0 or 0-1) in the bit block.
02560     Also calulates number of bits ON.
02561     
02562     @param bit_count - OUT total number of bits ON
02563     
02564     @return number of 1-0, 0-1 transitions
02565         
02566     @ingroup bitfunc 
02567 */
02568 inline 
02569 bm::id_t bit_block_calc_count_change(const bm::word_t* block, 
02570                                      const bm::word_t* block_end,
02571                                      unsigned*         bit_count)
02572 {
02573 #if defined(BMSSE2OPT) || defined(BMSSE42OPT)
02574 
02575 #ifdef BMSSE42OPT
02576     return sse4_bit_block_calc_count_change(
02577         (const __m128i*)block, (const __m128i*)block_end, bit_count);
02578 #else
02579 # ifdef BMSSE2OPT
02580     return sse2_bit_block_calc_count_change(
02581         (const __m128i*)block, (const __m128i*)block_end, bit_count);
02582 # endif
02583 #endif
02584 
02585 #else // non-SSE code
02586 
02587     BM_ASSERT(block < block_end);
02588     BM_ASSERT(bit_count);
02589     
02590     bm::id_t count = 1;
02591     *bit_count = 0;
02592     
02593 #ifdef BM64OPT
02594 
02595     // 64-bit optimized algorithm.
02596 
02597     const bm::id64_t* b1 = (bm::id64_t*) block;
02598     const bm::id64_t* b2 = (bm::id64_t*) block_end;
02599 
02600     bm::id64_t w, w0, w_prev, w_l;
02601     w = w0 = *b1;
02602     
02603     *bit_count = word_bitcount64(w);
02604     
02605     const int w_shift = sizeof(w) * 8 - 1;
02606     w ^= (w >> 1);
02607     count += word_bitcount64(w);
02608     count -= (w_prev = (w0 >> w_shift)); // negative value correction
02609 
02610     
02611     for (++b1 ;b1 < b2; ++b1)
02612     {
02613         w = w0 = *b1;
02614         
02615         ++count;
02616         
02617         if (!w)
02618         {
02619             count -= !w_prev;
02620             w_prev = 0;
02621         }
02622         else
02623         {
02624             *bit_count += word_bitcount64(w);
02625             w ^= (w >> 1);
02626             count += word_bitcount64(w);
02627             
02628             w_l = w0 & 1;
02629             count -= (w0 >> w_shift);  // negative value correction
02630             count -= !(w_prev ^ w_l);  // word border correction
02631             
02632             w_prev = (w0 >> w_shift);
02633         }
02634     } // for
02635 
02636 #else
02637     
02638     bm::word_t  w, w0, w_prev, w_l; 
02639     
02640     w = w0 = *block;
02641     
02642     BM_INCWORD_BITCOUNT(*bit_count, w);
02643     
02644     const int w_shift = sizeof(w) * 8 - 1;    
02645     w ^= (w >> 1);
02646     BM_INCWORD_BITCOUNT(count, w);
02647     count -= (w_prev = (w0 >> w_shift)); // negative value correction
02648 
02649     for (++block ;block < block_end; ++block)
02650     {
02651         w = w0 = *block;
02652         ++count;
02653 
02654         if (!w)
02655         {       
02656             count -= !w_prev;
02657             w_prev = 0;
02658         }
02659         else
02660         {
02661             BM_INCWORD_BITCOUNT(*bit_count, w);
02662         
02663             w ^= (w >> 1);
02664             BM_INCWORD_BITCOUNT(count, w);
02665             
02666             w_l = w0 & 1;
02667             count -= (w0 >> w_shift);  // negative value correction
02668             count -= !(w_prev ^ w_l);  // word border correction
02669             
02670             w_prev = (w0 >> w_shift);
02671         }
02672     } // for
02673 #endif
02674     return count;
02675 #endif
02676 }
02677 
02678 
02679 /*!
02680     Function calculates number of 1 bits in the given array of words in
02681     the range between left anf right bits (borders included)
02682     Make sure the addresses are aligned.
02683 
02684     @ingroup bitfunc
02685 */
02686 inline 
02687 bm::id_t bit_block_calc_count_range(const bm::word_t* block,
02688                                     bm::word_t left,
02689                                     bm::word_t right)
02690 {
02691     BM_ASSERT(left <= right);
02692     
02693     unsigned nbit  = left; // unsigned(left & bm::set_block_mask);
02694     unsigned nword = unsigned(nbit >> bm::set_word_shift);
02695     nbit &= bm::set_word_mask;
02696 
02697     const bm::word_t* word = block + nword;
02698 
02699     if (left == right)  // special case (only 1 bit to check)
02700     {
02701         return (*word >> nbit) & 1;
02702     }
02703     bm::id_t count = 0;
02704 
02705     unsigned acc;
02706     unsigned bitcount = right - left + 1;
02707 
02708     if (nbit) // starting position is not aligned
02709     {
02710         unsigned right_margin = nbit + (right - left);
02711 
02712         if (right_margin < 32)
02713         {
02714             unsigned mask =
02715                 block_set_table<true>::_right[nbit] &
02716                 block_set_table<true>::_left[right_margin];
02717             acc = *word & mask;
02718             
02719             BM_INCWORD_BITCOUNT(count, acc);
02720             return count;
02721         }
02722         else
02723         {
02724             acc = *word & block_set_table<true>::_right[nbit];
02725             BM_INCWORD_BITCOUNT(count, acc);
02726             bitcount -= 32 - nbit;
02727         }
02728         ++word;
02729     }
02730 
02731     // now when we are word aligned, we can count bits the usual way
02732     for ( ;bitcount >= 32; bitcount -= 32)
02733     {
02734         acc = *word++;
02735         BM_INCWORD_BITCOUNT(count, acc);
02736     }
02737 
02738     if (bitcount)  // we have a tail to count
02739     {
02740         acc = (*word) & block_set_table<true>::_left[bitcount-1];
02741         BM_INCWORD_BITCOUNT(count, acc);
02742     }
02743 
02744     return count;
02745 }
02746 
02747 
02748 /*!
02749     Function calculates if there is any number of 1 bits 
02750     in the given array of words in the range between left anf right bits 
02751     (borders included). Make sure the addresses are aligned.
02752 
02753     @ingroup bitfunc
02754 */
02755 inline 
02756 bm::id_t bit_block_any_range(const bm::word_t* block,
02757                              bm::word_t left,
02758                              bm::word_t right)
02759 {
02760     BM_ASSERT(left <= right);
02761     
02762     unsigned nbit  = left; // unsigned(left & bm::set_block_mask);
02763     unsigned nword = unsigned(nbit >> bm::set_word_shift);
02764     nbit &= bm::set_word_mask;
02765 
02766     const bm::word_t* word = block + nword;
02767 
02768     if (left == right)  // special case (only 1 bit to check)
02769     {
02770         return (*word >> nbit) & 1;
02771     }
02772     unsigned acc;
02773     unsigned bitcount = right - left + 1;
02774 
02775     if (nbit) // starting position is not aligned
02776     {
02777         unsigned right_margin = nbit + (right - left);
02778         if (right_margin < 32)
02779         {
02780             unsigned mask =
02781                 block_set_table<true>::_right[nbit] &
02782                 block_set_table<true>::_left[right_margin];
02783             acc = *word & mask;
02784             return acc;
02785         }
02786         else
02787         {
02788             acc = *word & block_set_table<true>::_right[nbit];
02789             if (acc) 
02790                 return acc;
02791             bitcount -= 32 - nbit;
02792         }
02793         ++word;
02794     }
02795 
02796     // now when we are word aligned, we can check bits the usual way
02797     for ( ;bitcount >= 32; bitcount -= 32)
02798     {
02799         acc = *word++;
02800         if (acc) 
02801             return acc;
02802     }
02803 
02804     if (bitcount)  // we have a tail to count
02805     {
02806         acc = (*word) & block_set_table<true>::_left[bitcount-1];
02807         if (acc) 
02808             return acc;
02809     }
02810 
02811     return 0;
02812 }
02813 
02814 
02815 
02816 // ----------------------------------------------------------------------
02817 
02818 /*! Function inverts block of bits 
02819     @ingroup bitfunc 
02820 */
02821 template<typename T> void bit_invert(T* start, T* end)
02822 {
02823 #ifdef BMVECTOPT
02824     VECT_INVERT_ARR(start, end);
02825 #else
02826     do
02827     {
02828         start[0] = ~start[0];
02829         start[1] = ~start[1];
02830         start[2] = ~start[2];
02831         start[3] = ~start[3];
02832         start+=4;
02833     } while (start < end);
02834 #endif
02835 }
02836 
02837 // ----------------------------------------------------------------------
02838 
02839 /*! @brief Returns "true" if all bits in the block are 1
02840     @ingroup bitfunc 
02841 */
02842 inline bool is_bits_one(const bm::wordop_t* start, 
02843                         const bm::wordop_t* end)
02844 {
02845    do
02846    {
02847         bm::wordop_t tmp = 
02848             start[0] & start[1] & start[2] & start[3];
02849         if (tmp != bm::all_bits_mask) 
02850             return false;
02851         start += 4;
02852    } while (start < end);
02853 
02854    return true;
02855 }
02856 
02857 // ----------------------------------------------------------------------
02858 
02859 
02860 /*! @brief Returns "true" if all bits in the block are 0
02861     @ingroup bitfunc 
02862 */
02863 inline bool bit_is_all_zero(const bm::wordop_t* start, 
02864                             const bm::wordop_t* end)
02865 {
02866    do
02867    {
02868         bm::wordop_t tmp = 
02869             start[0] | start[1] | start[2] | start[3];
02870        if (tmp) 
02871            return false;
02872        start += 4;
02873    } while (start < end);
02874 
02875    return true;
02876 }
02877 
02878 // ----------------------------------------------------------------------
02879 
02880 // GAP blocks manipulation functions:
02881 
02882 /*! \brief GAP and functor */
02883 inline unsigned and_op(unsigned v1, unsigned v2)
02884 {
02885     return v1 & v2;
02886 }
02887 
02888 
02889 /*! \brief GAP xor functor */
02890 inline unsigned xor_op(unsigned v1, unsigned v2)
02891 {
02892     return v1 ^ v2;
02893 }
02894 
02895 
02896 /*!
02897    \brief GAP AND operation.
02898    
02899    Function performs AND logical oparation on gap vectors.
02900    If possible function put the result into vect1 and returns this
02901    pointer.  Otherwise result is put into tmp_buf, which should be 
02902    twice of the vector size.
02903 
02904    \param vect1   - operand 1
02905    \param vect2   - operand 2
02906    \param tmp_buf - pointer on temporary buffer
02907    \param dsize   - out size of the destination
02908    \return Result pointer (tmp_buf OR vect1)
02909 
02910    @ingroup gapfunc
02911 */
02912 inline gap_word_t* gap_operation_and(const gap_word_t* BMRESTRICT vect1,
02913                                      const gap_word_t* BMRESTRICT vect2,
02914                                      gap_word_t*       BMRESTRICT tmp_buf,
02915                                      unsigned&         dsize)
02916 {
02917     gap_buff_op(tmp_buf, vect1, 0, vect2, 0, and_op, dsize);
02918     return tmp_buf;
02919 }
02920 
02921 /*!
02922    \brief GAP AND operation test.
02923    
02924    Function performs AND logical oparation on gap vectors.
02925    If possible function put the result into vect1 and returns this
02926    pointer.  Otherwise result is put into tmp_buf, which should be 
02927    twice of the vector size.
02928 
02929    \param vect1   - operand 1
02930    \param vect2   - operand 2
02931    \return non zero value if operation returns any 1 bit
02932 
02933    @ingroup gapfunc
02934 */
02935 inline unsigned gap_operation_any_and(const gap_word_t* BMRESTRICT vect1,
02936                                       const gap_word_t* BMRESTRICT vect2)
02937 {
02938     return gap_buff_any_op(vect1, 0, vect2, 0, and_op);
02939 }
02940 
02941 
02942 
02943 /*!
02944    \brief GAP XOR operation.
02945    
02946    Function performs XOR logical oparation on gap vectors.
02947    If possible function put the result into vect1 and returns this
02948    pointer.  Otherwise result is put into tmp_buf, which should be 
02949    twice of the vector size.
02950 
02951    \param vect1   - operand 1
02952    \param vect2   - operand 2
02953    \param tmp_buf - pointer on temporary buffer
02954    \param dsize   - out destination size
02955    \return Result pointer (tmp_buf)
02956 
02957    @ingroup gapfunc
02958 */
02959 inline gap_word_t* gap_operation_xor(const gap_word_t*  BMRESTRICT vect1,
02960                                      const gap_word_t*  BMRESTRICT vect2,
02961                                      gap_word_t*        BMRESTRICT tmp_buf,
02962                                      unsigned&                     dsize)
02963 {
02964     gap_buff_op(tmp_buf, vect1, 0, vect2, 0, xor_op, dsize);
02965     return tmp_buf;
02966 }
02967 
02968 
02969 /*!
02970    \brief GAP XOR operation test.
02971    
02972    Function performs AND logical oparation on gap vectors.
02973    If possible function put the result into vect1 and returns this
02974    pointer.  Otherwise result is put into tmp_buf, which should be 
02975    twice of the vector size.
02976 
02977    \param vect1   - operand 1
02978    \param vect2   - operand 2
02979    \return non zero value if operation returns any 1 bit
02980 
02981    @ingroup gapfunc
02982 */
02983 inline unsigned gap_operation_any_xor(const gap_word_t* BMRESTRICT vect1,
02984                                       const gap_word_t* BMRESTRICT vect2)
02985 {
02986     return gap_buff_any_op(vect1, 0, vect2, 0, xor_op);
02987 }
02988 
02989 
02990 
02991 /*!
02992    \brief GAP OR operation.
02993    
02994    Function performs OR logical oparation on gap vectors.
02995    If possible function put the result into vect1 and returns this
02996    pointer.  Otherwise result is put into tmp_buf, which should be 
02997    twice of the vector size.
02998 
02999    \param vect1   - operand 1
03000    \param vect2   - operand 2
03001    \param tmp_buf - pointer on temporary buffer
03002    \param dsize   - out destination size
03003 
03004    \return Result pointer (tmp_buf)
03005 
03006    @ingroup gapfunc
03007 */
03008 inline gap_word_t* gap_operation_or(const gap_word_t*  BMRESTRICT vect1,
03009                                     const gap_word_t*  BMRESTRICT vect2,
03010                                     gap_word_t*        BMRESTRICT tmp_buf,
03011                                     unsigned&                     dsize)
03012 {
03013     gap_buff_op(tmp_buf, vect1, 1, vect2, 1, and_op, dsize);
03014     gap_invert(tmp_buf);
03015     return tmp_buf;
03016 }
03017 
03018 
03019 
03020 
03021 /*!
03022    \brief GAP SUB (AND NOT) operation.
03023    
03024    Function performs SUB logical oparation on gap vectors.
03025    If possible function put the result into vect1 and returns this
03026    pointer.  Otherwise result is put into tmp_buf, which should be 
03027    twice of the vector size.
03028 
03029    \param vect1   - operand 1
03030    \param vect2   - operand 2
03031    \param tmp_buf - pointer on temporary buffer
03032    \param dsize   - out destination size
03033 
03034    \return Result pointer (tmp_buf)
03035 
03036    @ingroup gapfunc
03037 */
03038 inline gap_word_t* gap_operation_sub(const gap_word_t*  BMRESTRICT vect1,
03039                                      const gap_word_t*  BMRESTRICT vect2,
03040                                      gap_word_t*        BMRESTRICT tmp_buf,
03041                                      unsigned&                     dsize)
03042 {
03043     gap_buff_op(tmp_buf, vect1, 0, vect2, 1, and_op, dsize);    
03044     return tmp_buf;
03045 }
03046 
03047 
03048 /*!
03049    \brief GAP SUB operation test.
03050    
03051    Function performs AND logical oparation on gap vectors.
03052    If possible function put the result into vect1 and returns this
03053    pointer.  Otherwise result is put into tmp_buf, which should be 
03054    twice of the vector size.
03055 
03056    \param vect1   - operand 1
03057    \param vect2   - operand 2
03058    \return non zero value if operation returns any 1 bit
03059 
03060    @ingroup gapfunc
03061 */
03062 inline unsigned gap_operation_any_sub(const gap_word_t* BMRESTRICT vect1,
03063                                       const gap_word_t* BMRESTRICT vect2)
03064 {
03065     return gap_buff_any_op(vect1, 0, vect2, 1, and_op);    
03066 }
03067 
03068 
03069 // ----------------------------------------------------------------------
03070 
03071 // BIT blocks manipulation functions:
03072 
03073 
03074 /*!
03075    \brief Bitblock copy operation. 
03076 
03077    \param dst - destination block.
03078    \param src - source block.
03079 
03080    @ingroup bitfunc
03081 */
03082 inline 
03083 void bit_block_copy(bm::word_t* BMRESTRICT dst, const bm::word_t* BMRESTRICT src)
03084 {
03085 #ifdef BMVECTOPT
03086     VECT_COPY_BLOCK(dst, src, src + bm::set_block_size);
03087 #else
03088     ::memcpy(dst, src, bm::set_block_size * sizeof(bm::word_t));
03089 #endif
03090 }
03091 
03092 
03093 /*!
03094    \brief Plain bitblock AND operation. 
03095    Function does not analyse availability of source and destination blocks.
03096 
03097    \param dst - destination block.
03098    \param src - source block.
03099 
03100    @ingroup bitfunc
03101 */
03102 inline 
03103 void bit_block_and(bm::word_t* BMRESTRICT dst, const bm::word_t* BMRESTRICT src)
03104 {
03105 #ifdef BMVECTOPT
03106     VECT_AND_ARR(dst, src, src + bm::set_block_size);
03107 #else
03108     const bm::wordop_t* BMRESTRICT wrd_ptr = (wordop_t*)src;
03109     const bm::wordop_t* BMRESTRICT wrd_end = (wordop_t*)(src + bm::set_block_size);
03110     bm::wordop_t* BMRESTRICT dst_ptr = (wordop_t*)dst;
03111 
03112     do
03113     {
03114         dst_ptr[0] &= wrd_ptr[0];
03115         dst_ptr[1] &= wrd_ptr[1];
03116         dst_ptr[2] &= wrd_ptr[2];
03117         dst_ptr[3] &= wrd_ptr[3];
03118 
03119         dst_ptr+=4;
03120         wrd_ptr+=4;
03121     } while (wrd_ptr < wrd_end);
03122 #endif
03123 }
03124 
03125 
03126 /*!
03127    \brief Function ANDs two bitblocks and computes the bitcount. 
03128    Function does not analyse availability of source blocks.
03129 
03130    \param src1     - first bit block
03131    \param src1_end - first bit block end
03132    \param src2     - second bit block
03133 
03134    @ingroup bitfunc
03135 */
03136 inline 
03137 unsigned bit_block_and_count(const bm::word_t* src1, 
03138                              const bm::word_t* src1_end,
03139                              const bm::word_t* src2)
03140 {
03141     unsigned count;
03142 #ifdef BMVECTOPT
03143     count = VECT_BITCOUNT_AND(src1, src1_end, src2);
03144 #else  
03145     count = 0;  
03146     do
03147     {
03148         BM_INCWORD_BITCOUNT(count, src1[0] & src2[0]);
03149         BM_INCWORD_BITCOUNT(count, src1[1] & src2[1]);
03150         BM_INCWORD_BITCOUNT(count, src1[2] & src2[2]);
03151         BM_INCWORD_BITCOUNT(count, src1[3] & src2[3]);
03152 
03153         src1+=4;
03154         src2+=4;
03155     } while (src1 < src1_end);
03156 #endif    
03157     return count;
03158 }
03159 
03160 
03161 /*!
03162    \brief Function ANDs two bitblocks and tests for any bit. 
03163    Function does not analyse availability of source blocks.
03164 
03165    \param src1     - first bit block
03166    \param src1_end - first bit block end
03167    \param src2     - second bit block
03168 
03169    @ingroup bitfunc
03170 */
03171 inline 
03172 unsigned bit_block_and_any(const bm::word_t* src1, 
03173                            const bm::word_t* src1_end,
03174                            const bm::word_t* src2)
03175 {
03176     unsigned count = 0;
03177     do
03178     {
03179         count = (src1[0] & src2[0]) |
03180                 (src1[1] & src2[1]) |
03181                 (src1[2] & src2[2]) |
03182                 (src1[3] & src2[3]);
03183 
03184         src1+=4; src2+=4;
03185     } while ((src1 < src1_end) && (count == 0));
03186     return count;
03187 }
03188 
03189 
03190 
03191 
03192 /*!
03193    \brief Function XORs two bitblocks and computes the bitcount. 
03194    Function does not analyse availability of source blocks.
03195 
03196    \param src1     - first bit block.
03197    \param src1_end - first bit block end
03198    \param src2     - second bit block.
03199 
03200    @ingroup bitfunc
03201 */
03202 inline 
03203 unsigned bit_block_xor_count(const bm::word_t* BMRESTRICT src1,
03204                              const bm::word_t* BMRESTRICT src1_end, 
03205                              const bm::word_t* BMRESTRICT src2)
03206 {
03207     unsigned count;
03208 #ifdef BMVECTOPT
03209     count = VECT_BITCOUNT_XOR(src1, src1_end, src2);
03210 #else  
03211     count = 0;  
03212     do
03213     {
03214         BM_INCWORD_BITCOUNT(count, src1[0] ^ src2[0]);
03215         BM_INCWORD_BITCOUNT(count, src1[1] ^ src2[1]);
03216         BM_INCWORD_BITCOUNT(count, src1[2] ^ src2[2]);
03217         BM_INCWORD_BITCOUNT(count, src1[3] ^ src2[3]);
03218 
03219         src1+=4;
03220         src2+=4;
03221     } while (src1 < src1_end);
03222 #endif
03223     return count;
03224 }
03225 
03226 
03227 /*!
03228    \brief Function XORs two bitblocks and and tests for any bit.
03229    Function does not analyse availability of source blocks.
03230 
03231    \param src1     - first bit block.
03232    \param src1_end - first bit block end
03233    \param src2     - second bit block.
03234 
03235    @ingroup bitfunc
03236 */
03237 inline 
03238 unsigned bit_block_xor_any(const bm::word_t* BMRESTRICT src1,
03239                              const bm::word_t* BMRESTRICT src1_end, 
03240                              const bm::word_t* BMRESTRICT src2)
03241 {
03242     unsigned count = 0;
03243     do
03244     {
03245         count = (src1[0] ^ src2[0]) |
03246                 (src1[1] ^ src2[1]) |
03247                 (src1[2] ^ src2[2]) |
03248                 (src1[3] ^ src2[3]);
03249 
03250         src1+=4; src2+=4;
03251     } while ((src1 < src1_end) && (count == 0));
03252     return count;
03253 }
03254 
03255 
03256 
03257 
03258 /*!
03259    \brief Function SUBs two bitblocks and computes the bitcount. 
03260    Function does not analyse availability of source blocks.
03261 
03262    \param src1     - first bit block.
03263    \param src1_end - first bit block end
03264    \param src2     - second bit block.
03265 
03266    @ingroup bitfunc
03267 */
03268 inline 
03269 unsigned bit_block_sub_count(const bm::word_t* BMRESTRICT src1, 
03270                              const bm::word_t* BMRESTRICT src1_end, 
03271                              const bm::word_t* BMRESTRICT src2)
03272 {
03273     unsigned count;
03274 #ifdef BMVECTOPT
03275     count = VECT_BITCOUNT_SUB(src1, src1_end, src2);
03276 #else  
03277     count = 0;  
03278     do
03279     {
03280         BM_INCWORD_BITCOUNT(count, src1[0] & ~src2[0]);
03281         BM_INCWORD_BITCOUNT(count, src1[1] & ~src2[1]);
03282         BM_INCWORD_BITCOUNT(count, src1[2] & ~src2[2]);
03283         BM_INCWORD_BITCOUNT(count, src1[3] & ~src2[3]);
03284 
03285         src1+=4;
03286         src2+=4;
03287     } while (src1 < src1_end);
03288 #endif
03289     return count;
03290 }
03291 
03292 /*!
03293    \brief Function SUBs two bitblocks and and tests for any bit.
03294    Function does not analyse availability of source blocks.
03295 
03296    \param src1     - first bit block.
03297    \param src1_end - first bit block end
03298    \param src2     - second bit block.
03299 
03300    @ingroup bitfunc
03301 */
03302 inline 
03303 unsigned bit_block_sub_any(const bm::word_t* BMRESTRICT src1,
03304                              const bm::word_t* BMRESTRICT src1_end, 
03305                              const bm::word_t* BMRESTRICT src2)
03306 {
03307     unsigned count = 0;
03308     do
03309     {
03310         count = (src1[0] & ~src2[0]) |
03311                 (src1[1] & ~src2[1]) |
03312                 (src1[2] & ~src2[2]) |
03313                 (src1[3] & ~src2[3]);
03314 
03315         src1+=4; src2+=4;
03316     } while ((src1 < src1_end) && (count == 0));
03317     return count;
03318 }
03319 
03320 
03321 
03322 /*!
03323    \brief Function ORs two bitblocks and computes the bitcount. 
03324    Function does not analyse availability of source blocks.
03325 
03326    \param src1     - first bit block
03327    \param src1_end - first block end
03328    \param src2     - second bit block.
03329 
03330    @ingroup bitfunc
03331 */
03332 inline 
03333 unsigned bit_block_or_count(const bm::word_t* src1, 
03334                             const bm::word_t* src1_end,
03335                             const bm::word_t* src2)
03336 {
03337     unsigned count;
03338 #ifdef BMVECTOPT
03339     count = VECT_BITCOUNT_OR(src1, src1_end, src2);
03340 #else  
03341     count = 0;  
03342     do
03343     {
03344         BM_INCWORD_BITCOUNT(count, src1[0] | src2[0]);
03345         BM_INCWORD_BITCOUNT(count, src1[1] | src2[1]);
03346         BM_INCWORD_BITCOUNT(count, src1[2] | src2[2]);
03347         BM_INCWORD_BITCOUNT(count, src1[3] | src2[3]);
03348 
03349         src1+=4;
03350         src2+=4;
03351     } while (src1 < src1_end);
03352 #endif
03353     return count;
03354 }
03355 
03356 /*!
03357    \brief Function ORs two bitblocks and and tests for any bit.
03358    Function does not analyse availability of source blocks.
03359 
03360    \param src1     - first bit block.
03361    \param src1_end - first bit block end
03362    \param src2     - second bit block.
03363 
03364    @ingroup bitfunc
03365 */
03366 inline 
03367 unsigned bit_block_or_any(const bm::word_t* BMRESTRICT src1,
03368                           const bm::word_t* BMRESTRICT src1_end, 
03369                           const bm::word_t* BMRESTRICT src2)
03370 {
03371     unsigned count = 0;
03372     do
03373     {
03374         count = (src1[0] | src2[0]) |
03375                 (src1[1] | src2[1]) |
03376                 (src1[2] | src2[2]) |
03377                 (src1[3] | src2[3]);
03378 
03379         src1+=4; src2+=4;
03380     } while ((src1 < src1_end) && (count == 0));
03381     return count;
03382 }
03383 
03384 
03385 
03386 
03387 /*!
03388    \brief bitblock AND operation. 
03389 
03390    \param dst - destination block.
03391    \param src - source block.
03392 
03393    \returns pointer on destination block. 
03394     If returned value  equal to src means that block mutation requested. 
03395     NULL is valid return value.
03396 
03397    @ingroup bitfunc
03398 */
03399 inline bm::word_t* bit_operation_and(bm::word_t* BMRESTRICT dst, 
03400                                      const bm::word_t* BMRESTRICT src)
03401 {
03402     BM_ASSERT(dst || src);
03403 
03404     bm::word_t* ret = dst;
03405 
03406     if (IS_VALID_ADDR(dst))  // The destination block already exists
03407     {
03408 
03409         if (!IS_VALID_ADDR(src))
03410         {
03411             if (IS_EMPTY_BLOCK(src))
03412             {
03413                 //If the source block is zero 
03414                 //just clean the destination block
03415                 return 0;
03416             }
03417         }
03418         else
03419         {
03420             // Regular operation AND on the whole block.
03421             bit_block_and(dst, src);
03422         }
03423     }
03424     else // The destination block does not exist yet
03425     {
03426         if(!IS_VALID_ADDR(src))
03427         {
03428             if(IS_EMPTY_BLOCK(src)) 
03429             {
03430                 // The source block is empty.
03431                 // One argument empty - all result is empty.
03432                 return 0;
03433             }
03434             // Here we have nothing to do.
03435             // Src block is all ON, dst block remains as it is
03436         }
03437         else // destination block does not exists, src - valid block
03438         {
03439             if (IS_FULL_BLOCK(dst))
03440             {
03441                 return const_cast<bm::word_t*>(src);
03442             }
03443             // Nothng to do.
03444             // Dst block is all ZERO no combination required.
03445         }
03446     }
03447 
03448     return ret;
03449 }
03450 
03451 
03452 /*!
03453    \brief Performs bitblock AND operation and calculates bitcount of the result. 
03454 
03455    \param src1     - first bit block.
03456    \param src1_end - first bit block end
03457    \param src2     - second bit block.
03458 
03459    \returns bitcount value 
03460 
03461    @ingroup bitfunc
03462 */
03463 inline 
03464 bm::id_t bit_operation_and_count(const bm::word_t* BMRESTRICT src1,
03465                                  const bm::word_t* BMRESTRICT src1_end,
03466                                  const bm::word_t* BMRESTRICT src2)
03467 {
03468     if (IS_EMPTY_BLOCK(src1) || IS_EMPTY_BLOCK(src2))
03469     {
03470         return 0;
03471     }
03472     return bit_block_and_count(src1, src1_end, src2);
03473 }
03474 
03475 /*!
03476    \brief Performs bitblock AND operation test. 
03477 
03478    \param src1     - first bit block.
03479    \param src1_end - first bit block end
03480    \param src2     - second bit block.
03481 
03482    \returns non zero if there is any value 
03483 
03484    @ingroup bitfunc
03485 */
03486 inline 
03487 bm::id_t bit_operation_and_any(const bm::word_t* BMRESTRICT src1,
03488                                const bm::word_t* BMRESTRICT src1_end,
03489                                const bm::word_t* BMRESTRICT src2)
03490 {
03491     if (IS_EMPTY_BLOCK(src1) || IS_EMPTY_BLOCK(src2))
03492     {
03493         return 0;
03494     }
03495     return bit_block_and_any(src1, src1_end, src2);
03496 }
03497 
03498 
03499 
03500 /*!
03501    \brief Performs bitblock SUB operation and calculates bitcount of the result. 
03502 
03503    \param src1      - first bit block.
03504    \param src1_end  - first bit block end
03505    \param src2      - second bit block
03506 
03507    \returns bitcount value 
03508 
03509    @ingroup bitfunc
03510 */
03511 inline 
03512 bm::id_t bit_operation_sub_count(const bm::word_t* BMRESTRICT src1, 
03513                                  const bm::word_t* BMRESTRICT src1_end,
03514                                  const bm::word_t* BMRESTRICT src2)
03515 {
03516     if (IS_EMPTY_BLOCK(src1))
03517     {
03518         return 0;
03519     }
03520     
03521     if (IS_EMPTY_BLOCK(src2)) // nothing to diff
03522     {
03523         return bit_block_calc_count(src1, src1_end);
03524     }
03525     return bit_block_sub_count(src1, src1_end, src2);
03526 }
03527 
03528 
03529 /*!
03530    \brief Performs inverted bitblock SUB operation and calculates 
03531           bitcount of the result. 
03532 
03533    \param src1      - first bit block.
03534    \param src1_end  - first bit block end
03535    \param src2      - second bit block
03536 
03537    \returns bitcount value 
03538 
03539    @ingroup bitfunc
03540 */
03541 inline 
03542 bm::id_t bit_operation_sub_count_inv(const bm::word_t* BMRESTRICT src1, 
03543                                      const bm::word_t* BMRESTRICT src1_end,
03544                                      const bm::word_t* BMRESTRICT src2)
03545 {
03546     unsigned arr_size = unsigned(src1_end - src1);
03547     return bit_operation_sub_count(src2, src2+arr_size, src1);
03548 }
03549 
03550 
03551 /*!
03552    \brief Performs bitblock test of SUB operation. 
03553 
03554    \param src1      - first bit block.
03555    \param src1_end  - first bit block end
03556    \param src2      - second bit block
03557 
03558    \returns non zero value if there are any bits
03559 
03560    @ingroup bitfunc
03561 */
03562 inline 
03563 bm::id_t bit_operation_sub_any(const bm::word_t* BMRESTRICT src1, 
03564                                const bm::word_t* BMRESTRICT src1_end,
03565                                const bm::word_t* BMRESTRICT src2)
03566 {
03567     if (IS_EMPTY_BLOCK(src1))
03568     {
03569         return 0;
03570     }
03571     
03572     if (IS_EMPTY_BLOCK(src2)) // nothing to diff
03573     {
03574         return !bit_is_all_zero((bm::wordop_t*)src1, (bm::wordop_t*)src1_end);
03575     }
03576     return bit_block_sub_any(src1, src1_end, src2);
03577 }
03578 
03579 
03580 
03581 /*!
03582    \brief Performs bitblock OR operation and calculates bitcount of the result. 
03583 
03584    \param src1     - first bit block.
03585    \param src1_end - first bit block end
03586    \param src2     - second bit block.
03587 
03588    \returns bitcount value 
03589 
03590    @ingroup bitfunc
03591 */
03592 inline 
03593 bm::id_t bit_operation_or_count(const bm::word_t* BMRESTRICT src1,
03594                                 const bm::word_t* BMRESTRICT src1_end, 
03595                                 const bm::word_t* BMRESTRICT src2)
03596 {
03597     if (IS_EMPTY_BLOCK(src1))
03598     {
03599         if (!IS_EMPTY_BLOCK(src2))
03600             return bit_block_calc_count(src2, src2 + (src1_end - src1));
03601         else
03602             return 0; // both blocks are empty        
03603     }
03604     else
03605     {
03606         if (IS_EMPTY_BLOCK(src2))
03607             return bit_block_calc_count(src1, src1_end);
03608     }
03609 
03610     return bit_block_or_count(src1, src1_end, src2);
03611 }
03612 
03613 /*!
03614    \brief Performs bitblock OR operation test. 
03615 
03616    \param src1     - first bit block.
03617    \param src1_end - first bit block end
03618    \param src2     - second bit block.
03619 
03620    \returns non zero value if there are any bits
03621 
03622    @ingroup bitfunc
03623 */
03624 inline 
03625 bm::id_t bit_operation_or_any(const bm::word_t* BMRESTRICT src1,
03626                               const bm::word_t* BMRESTRICT src1_end, 
03627                               const bm::word_t* BMRESTRICT src2)
03628 {
03629     if (IS_EMPTY_BLOCK(src1))
03630     {
03631         if (!IS_EMPTY_BLOCK(src2))
03632             return !bit_is_all_zero((bm::wordop_t*)src2, 
03633                                      (bm::wordop_t*)(src2 + (src1_end - src1)));
03634         else
03635             return 0; // both blocks are empty        
03636     }
03637     else
03638     {
03639         if (IS_EMPTY_BLOCK(src2))
03640             return !bit_is_all_zero((bm::wordop_t*)src1, (bm::wordop_t*)src1_end);
03641     }
03642 
03643     return bit_block_or_any(src1, src1_end, src2);
03644 }
03645 
03646 
03647 
03648 /*!
03649    \brief Plain bitblock OR operation. 
03650    Function does not analyse availability of source and destination blocks.
03651 
03652    \param dst - destination block.
03653    \param src - source block.
03654 
03655    @ingroup bitfunc
03656 */
03657 inline void bit_block_or(bm::word_t* BMRESTRICT dst, 
03658                          const bm::word_t* BMRESTRICT src)
03659 {
03660 #ifdef BMVECTOPT
03661     VECT_OR_ARR(dst, src, src + bm::set_block_size);
03662 #else
03663     const bm::wordop_t* BMRESTRICT wrd_ptr = (wordop_t*)src;
03664     const bm::wordop_t* BMRESTRICT wrd_end = (wordop_t*)(src + set_block_size);
03665     bm::wordop_t* BMRESTRICT dst_ptr = (wordop_t*)dst;
03666 
03667     do
03668     {
03669         dst_ptr[0] |= wrd_ptr[0];
03670         dst_ptr[1] |= wrd_ptr[1];
03671         dst_ptr[2] |= wrd_ptr[2];
03672         dst_ptr[3] |= wrd_ptr[3];
03673 
03674         dst_ptr+=4;
03675         wrd_ptr+=4;
03676 
03677     } while (wrd_ptr < wrd_end);
03678 #endif
03679 }
03680 
03681 
03682 /*!
03683    \brief Block OR operation. Makes analysis if block is 0 or FULL. 
03684 
03685    \param dst - destination block.
03686    \param src - source block.
03687 
03688    \returns pointer on destination block. 
03689     If returned value  equal to src means that block mutation requested. 
03690     NULL is valid return value.
03691 
03692    @ingroup bitfunc
03693 */
03694 inline 
03695 bm::word_t* bit_operation_or(bm::word_t* BMRESTRICT dst, 
03696                              const bm::word_t* BMRESTRICT src)
03697 {
03698     BM_ASSERT(dst || src);
03699 
03700     bm::word_t* ret = dst;
03701 
03702     if (IS_VALID_ADDR(dst)) // The destination block already exists
03703     {
03704         if (!IS_VALID_ADDR(src))
03705         {
03706             if (IS_FULL_BLOCK(src))
03707             {
03708                 // if the source block is all set 
03709                 // just set the destination block
03710                 ::memset(dst, 0xFF, bm::set_block_size * sizeof(bm::word_t));
03711             }
03712         }
03713         else
03714         {
03715             // Regular operation OR on the whole block
03716             bit_block_or(dst, src);
03717         }
03718     }
03719     else // The destination block does not exist yet
03720     {
03721         if (!IS_VALID_ADDR(src))
03722         {
03723             if (IS_FULL_BLOCK(src)) 
03724             {
03725                 // The source block is all set, because dst does not exist
03726                 // we can simply replace it.
03727                 return const_cast<bm::word_t*>(FULL_BLOCK_ADDR);
03728             }
03729         }
03730         else
03731         {
03732             if (dst == 0)
03733             {
03734                 // The only case when we have to allocate the new block:
03735                 // Src is all zero and Dst does not exist
03736                 return const_cast<bm::word_t*>(src);
03737             }
03738         }
03739     }
03740     return ret;
03741 }
03742 
03743 /*!
03744    \brief Plain bitblock SUB (AND NOT) operation. 
03745    Function does not analyse availability of source and destination blocks.
03746 
03747    \param dst - destination block.
03748    \param src - source block.
03749 
03750    @ingroup bitfunc
03751 */
03752 inline 
03753 void bit_block_sub(bm::word_t* BMRESTRICT dst, 
03754                    const bm::word_t* BMRESTRICT src)
03755 {
03756 #ifdef BMVECTOPT
03757     VECT_SUB_ARR(dst, src, src + bm::set_block_size);
03758 #else
03759     const bm::wordop_t* BMRESTRICT wrd_ptr = (wordop_t*) src;
03760     const bm::wordop_t* BMRESTRICT wrd_end = 
03761                      (wordop_t*) (src + bm::set_block_size);
03762     bm::wordop_t* dst_ptr = (wordop_t*)dst;
03763     
03764     // Regular operation AND-NOT on the whole block.
03765     do
03766     {
03767         dst_ptr[0] &= ~wrd_ptr[0];
03768         dst_ptr[1] &= ~wrd_ptr[1];
03769         dst_ptr[2] &= ~wrd_ptr[2];
03770         dst_ptr[3] &= ~wrd_ptr[3];
03771 
03772         dst_ptr+=4;
03773         wrd_ptr+=4;
03774     } while (wrd_ptr < wrd_end);
03775 #endif
03776     
03777 }
03778 
03779 
03780 /*!
03781    \brief bitblock SUB operation. 
03782 
03783    \param dst - destination block.
03784    \param src - source block.
03785 
03786    \returns pointer on destination block. 
03787     If returned value  equal to src means that block mutation requested. 
03788     NULL is valid return value.
03789 
03790    @ingroup bitfunc
03791 */
03792 inline 
03793 bm::word_t* bit_operation_sub(bm::word_t* BMRESTRICT dst, 
03794                               const bm::word_t* BMRESTRICT src)
03795 {
03796     BM_ASSERT(dst || src);
03797 
03798     bm::word_t* ret = dst;
03799     if (IS_VALID_ADDR(dst))  //  The destination block already exists
03800     {
03801         if (!IS_VALID_ADDR(src))
03802         {
03803             if (IS_FULL_BLOCK(src))
03804             {
03805                 // If the source block is all set
03806                 // just clean the destination block
03807                 return 0;
03808             }
03809         }
03810         else
03811         {
03812             bit_block_sub(dst, src);
03813         }
03814     }
03815     else // The destination block does not exist yet
03816     {
03817         if (!IS_VALID_ADDR(src))
03818         {
03819             if (IS_FULL_BLOCK(src)) 
03820             {
03821                 // The source block is full
03822                 return 0;
03823             }
03824         }
03825         else
03826         {
03827             if (IS_FULL_BLOCK(dst))
03828             {
03829                 // The only case when we have to allocate the new block:
03830                 // dst is all set and src exists
03831                 return const_cast<bm::word_t*>(src);                  
03832             }
03833         }
03834     }
03835     return ret;
03836 }
03837 
03838 
03839 /*!
03840    \brief Plain bitblock XOR operation. 
03841    Function does not analyse availability of source and destination blocks.
03842 
03843    \param dst - destination block.
03844    \param src - source block.
03845 
03846    @ingroup bitfunc
03847 */
03848 inline 
03849 void bit_block_xor(bm::word_t* BMRESTRICT dst, 
03850                    const bm::word_t* BMRESTRICT src)
03851 {
03852 #ifdef BMVECTOPT
03853     VECT_XOR_ARR(dst, src, src + bm::set_block_size);
03854 #else
03855     const bm::wordop_t* BMRESTRICT wrd_ptr = (wordop_t*) src;
03856     const bm::wordop_t* BMRESTRICT wrd_end = 
03857                             (wordop_t*) (src + bm::set_block_size);
03858     bm::wordop_t* BMRESTRICT dst_ptr = (wordop_t*)dst;
03859 
03860     // Regular XOR operation on the whole block.
03861     do
03862     {
03863         dst_ptr[0] ^= wrd_ptr[0];
03864         dst_ptr[1] ^= wrd_ptr[1];
03865         dst_ptr[2] ^= wrd_ptr[2];
03866         dst_ptr[3] ^= wrd_ptr[3];
03867 
03868         dst_ptr+=4;
03869         wrd_ptr+=4;
03870     } while (wrd_ptr < wrd_end);
03871 #endif
03872     
03873 }
03874 
03875 
03876 /*!
03877    \brief bitblock XOR operation. 
03878 
03879    \param dst - destination block.
03880    \param src - source block.
03881 
03882    \returns pointer on destination block. 
03883     If returned value  equal to src means that block mutation requested. 
03884     NULL is valid return value.
03885 
03886    @ingroup bitfunc
03887 */
03888 inline 
03889 bm::word_t* bit_operation_xor(bm::word_t* BMRESTRICT dst, 
03890                               const bm::word_t* BMRESTRICT src)
03891 {
03892     BM_ASSERT(dst || src);
03893     if (src == dst) return 0;  // XOR rule  
03894 
03895     bm::word_t* ret = dst;
03896 
03897     if (IS_VALID_ADDR(dst))  //  The destination block already exists
03898     {           
03899         if (!src) return dst;
03900         
03901         bit_block_xor(dst, src);
03902     }
03903     else // The destination block does not exist yet
03904     {
03905         if (!src) return dst;      // 1 xor 0 = 1
03906 
03907         // Here we have two cases:
03908         // if dest block is full or zero if zero we need to copy the source
03909         // otherwise XOR loop against 0xFF...
03910         //BM_ASSERT(dst == 0);
03911         return const_cast<bm::word_t*>(src);  // src is the final result               
03912     }
03913     return ret;
03914 }
03915 
03916 /*!
03917    \brief Performs bitblock XOR operation and calculates bitcount of the result. 
03918 
03919    \param src1 - first bit block.
03920    \param src2 - second bit block.
03921 
03922    \returns bitcount value 
03923 
03924    @ingroup bitfunc
03925 */
03926 inline 
03927 bm::id_t bit_operation_xor_count(const bm::word_t* BMRESTRICT src1,
03928                                  const bm::word_t* BMRESTRICT src1_end,
03929                                  const bm::word_t* BMRESTRICT src2)
03930 {
03931     if (IS_EMPTY_BLOCK(src1) || IS_EMPTY_BLOCK(src2))
03932     {
03933         if (IS_EMPTY_BLOCK(src1) && IS_EMPTY_BLOCK(src2))
03934             return 0;
03935         const bm::word_t* block = IS_EMPTY_BLOCK(src1) ? src2 : src1;
03936         return bit_block_calc_count(block, block + (src1_end - src1));
03937     }
03938     return bit_block_xor_count(src1, src1_end, src2);
03939 }
03940 
03941 /*!
03942    \brief Performs bitblock XOR operation test. 
03943 
03944    \param src1 - first bit block.
03945    \param src2 - second bit block.
03946 
03947    \returns non zero value if there are bits
03948 
03949    @ingroup bitfunc
03950 */
03951 inline 
03952 bm::id_t bit_operation_xor_any(const bm::word_t* BMRESTRICT src1,
03953                                const bm::word_t* BMRESTRICT src1_end,
03954                                const bm::word_t* BMRESTRICT src2)
03955 {
03956     if (IS_EMPTY_BLOCK(src1) || IS_EMPTY_BLOCK(src2))
03957     {
03958         if (IS_EMPTY_BLOCK(src1) && IS_EMPTY_BLOCK(src2))
03959             return 0;
03960         const bm::word_t* block = IS_EMPTY_BLOCK(src1) ? src2 : src1;
03961         return !bit_is_all_zero((bm::wordop_t*)block, 
03962                                 (bm::wordop_t*)(block + (src1_end - src1)));
03963     }
03964     return bit_block_xor_any(src1, src1_end, src2);
03965 }
03966 
03967 
03968 
03969 /**
03970     \brief Inspects block for full zero words 
03971 
03972     \param data - bit block pointer
03973     \param data_size - data size
03974 
03975     \return size of all non-zero words
03976 
03977     @ingroup bitfunc
03978 */
03979 
03980 template<class T>
03981 unsigned bit_count_nonzero_size(const T*     blk, 
03982                                 unsigned     data_size)
03983 {
03984     BM_ASSERT(blk && data_size);
03985     unsigned count = 0;
03986     //unsigned i,j,k;
03987     const T* blk_end = blk + data_size - 2;
03988 
03989     //for (i = 0; i < data_size; ++i)
03990     //for (; blk < blk_end; ++blk) 
03991     do
03992     {
03993         if (*blk == 0) // (blk[i] == 0)
03994         {
03995             // scan fwd to find 0 island length
03996             //for (j = i+1; j < data_size; ++j)
03997             const T* blk_j = blk + 1;
03998             for (; blk_j < blk_end; ++blk_j)
03999             {
04000                 if (*blk_j != 0)//(blk[j] != 0)
04001                     break;
04002             }
04003             //i = j - 1;
04004             blk = blk_j-1;
04005             count += sizeof(gap_word_t);
04006         }
04007         else
04008         {
04009             // scan fwd to find non-0 island length
04010             //for (j = i+1; j < data_size; ++j)
04011             const T* blk_j = blk + 1;
04012             for ( ; blk_j < blk_end; ++blk_j)
04013             {
04014                 // if (blk[j] == 0)
04015                 if (*blk_j == 0)
04016                 {
04017                     // look ahead to identify and ignore short 0-run
04018 //                    if (((blk_j+1 < blk_end) && blk_j[1]) ||
04019 //                        ((blk_j+2 < blk_end) && blk_j[2])
04020 //                       )
04021                     if (blk_j[1] | blk_j[2])
04022                     {
04023                         //++j; 
04024                         // skip zero word
04025                         ++blk_j;
04026                         continue;
04027                     }
04028                     break;
04029                 }
04030             }
04031             count += sizeof(gap_word_t);
04032             // count all bit-words now
04033             count += (blk_j - blk) * sizeof(T);
04034             blk = blk_j;
04035             
04036             //for (k = i; k < j; ++k)
04037             //{
04038             //    count += sizeof(blk[k]);
04039             //}
04040             //i = k - 1;
04041         }
04042         ++blk;
04043     }
04044     while(blk < blk_end); 
04045 
04046     return count + (2 * sizeof(T));
04047 }
04048 
04049 
04050 /**
04051     \brief Searches for the next 1 bit in the BIT block
04052     \param data - BIT buffer
04053     \param nbit - bit index to start checking from
04054     \param prev - returns previously checked value
04055 
04056     @ingroup bitfunc
04057 */
04058 inline 
04059 int bit_find_in_block(const bm::word_t* data, 
04060                       unsigned          nbit, 
04061                       bm::id_t*         prev)
04062 {
04063     register bm::id_t p = *prev;
04064     int found = 0;
04065 
04066     for(;;)
04067     {
04068         unsigned nword  = nbit >> bm::set_word_shift;
04069         if (nword >= bm::set_block_size) break;
04070 
04071         register bm::word_t val = data[nword] >> (p & bm::set_word_mask);
04072 
04073         if (val)
04074         {
04075             while((val & 1) == 0)
04076             {
04077                 val >>= 1;
04078                 ++nbit;
04079                 ++p;
04080             }
04081             ++found;
04082 
04083             break;
04084         }
04085         else
04086         {
04087            p    += (bm::set_word_mask + 1) - (nbit & bm::set_word_mask);
04088            nbit += (bm::set_word_mask + 1) - (nbit & bm::set_word_mask);
04089         }
04090     }
04091     *prev = p;
04092     return found;
04093 }
04094 
04095 /*!
04096    \brief Templated algorithm to unpacks octet based word into list of ON bit indexes
04097    \param w - value
04098    \param func - bit functor 
04099 
04100    @ingroup bitfunc
04101 */
04102 template<typename T, typename F> 
04103 void bit_for_each_4(T w, F& func)
04104 {
04105     for (unsigned sub_octet = 0; w != 0; w >>= 4, sub_octet += 4)
04106     {
04107         switch (w & 15)
04108         {
04109         case 0: // 0000
04110             break;
04111         case 1: // 0001
04112             func(sub_octet);
04113             break;
04114         case 2: // 0010
04115             func(sub_octet + 1);
04116             break;
04117         case 3: // 0011
04118             func(sub_octet, sub_octet + 1);
04119             break;
04120         case 4: // 0100
04121             func(sub_octet + 2);
04122             break;
04123         case 5: // 0101
04124             func(sub_octet, sub_octet + 2);
04125             break;
04126         case 6: // 0110
04127             func(sub_octet + 1, sub_octet + 2);
04128             break;
04129         case 7: // 0111
04130             func(sub_octet, sub_octet + 1, sub_octet + 2);
04131             break;
04132         case 8: // 1000
04133             func(sub_octet + 3);
04134             break;
04135         case 9: // 1001
04136             func(sub_octet, sub_octet + 3);
04137             break;
04138         case 10: // 1010
04139             func(sub_octet + 1, sub_octet + 3);
04140             break;
04141         case 11: // 1011
04142             func(sub_octet, sub_octet + 1, sub_octet + 3);
04143             break;
04144         case 12: // 1100
04145             func(sub_octet + 2, sub_octet + 3);
04146             break;
04147         case 13: // 1101
04148             func(sub_octet, sub_octet + 2, sub_octet + 3);
04149             break;
04150         case 14: // 1110
04151             func(sub_octet + 1, sub_octet + 2, sub_octet + 3);
04152             break;
04153         case 15: // 1111
04154             func(sub_octet, sub_octet + 1, sub_octet + 2, sub_octet + 3);
04155             break;
04156         default:
04157             BM_ASSERT(0);
04158             break;
04159         }
04160         
04161     } // for
04162 }
04163 
04164 
04165 /*!
04166    \brief Templated algorithm to unpacks word into list of ON bit indexes
04167    \param w - value
04168    \param func - bit functor 
04169 
04170    @ingroup bitfunc
04171 */
04172 template<typename T, typename F> 
04173 void bit_for_each(T w, F& func)
04174 {
04175     // Note: 4-bit table method works slower than plain check approach
04176     for (unsigned octet = 0; w != 0; w >>= 8, octet += 8)
04177     {
04178         if (w & 1)   func(octet + 0);
04179         if (w & 2)   func(octet + 1);
04180         if (w & 4)   func(octet + 2);
04181         if (w & 8)   func(octet + 3);
04182         if (w & 16)  func(octet + 4);
04183         if (w & 32)  func(octet + 5);
04184         if (w & 64)  func(octet + 6);
04185         if (w & 128) func(octet + 7);
04186         
04187     } // for
04188 }
04189 
04190 /*! @brief Adaptor to copy 1 bits to array
04191     @internal
04192 */
04193 template<typename B> class copy_to_array_functor
04194 {
04195 public:
04196     copy_to_array_functor(B* bits): bp_(bits)
04197     {}
04198 
04199     B* ptr() { return bp_; }
04200     
04201     void operator()(unsigned bit_idx) { *bp_++ = (B)bit_idx; }
04202     
04203     void operator()(unsigned bit_idx0, 
04204                     unsigned bit_idx1) 
04205     { 
04206         bp_[0] = (B)bit_idx0; bp_[1] = (B)bit_idx1;
04207         bp_+=2;
04208     }
04209     
04210     void operator()(unsigned bit_idx0, 
04211                     unsigned bit_idx1, 
04212                     unsigned bit_idx2) 
04213     { 
04214         bp_[0] = (B)bit_idx0; bp_[1] = (B)bit_idx1; bp_[2] = (B)bit_idx2;
04215         bp_+=3;
04216     }
04217     
04218     void operator()(unsigned bit_idx0, 
04219                     unsigned bit_idx1, 
04220                     unsigned bit_idx2, 
04221                     unsigned bit_idx3) 
04222     { 
04223         bp_[0] = (B)bit_idx0; bp_[1] = (B)bit_idx1;
04224         bp_[2] = (B)bit_idx2; bp_[3] = (B)bit_idx3;
04225         bp_+=4;
04226     }
04227 
04228 private:
04229     copy_to_array_functor(const copy_to_array_functor&);
04230     copy_to_array_functor& operator=(const copy_to_array_functor&);
04231 private:
04232     B* bp_;
04233 };
04234 
04235 /*! @brief Adaptor to copy 1 bits to array with base increment
04236     @internal
04237 */
04238 template<typename B> class copy_to_array_functor_inc
04239 {
04240 public:
04241     copy_to_array_functor_inc(B* bits, unsigned base_idx)
04242     : bp_(bits), base_idx_(base_idx)
04243     {}
04244 
04245     B* ptr() { return bp_; }
04246     
04247     void operator()(unsigned bit_idx) 
04248     { 
04249         *bp_++ = (B)(bit_idx + base_idx_);
04250     }
04251 
04252     
04253     void operator()(unsigned bit_idx0, 
04254                     unsigned bit_idx1) 
04255     { 
04256         bp_[0]=(B)(bit_idx0+base_idx_);bp_[1]=(B)(bit_idx1+base_idx_);
04257         bp_+=2;
04258     }
04259     
04260     void operator()(unsigned bit_idx0, 
04261                     unsigned bit_idx1, 
04262                     unsigned bit_idx2) 
04263     { 
04264         bp_[0]=(B)(bit_idx0+base_idx_);bp_[1]=(B)(bit_idx1+base_idx_);
04265         bp_[2]=(B)(bit_idx2+base_idx_);
04266         bp_+=3;
04267     }
04268     
04269     void operator()(unsigned bit_idx0, 
04270                     unsigned bit_idx1, 
04271                     unsigned bit_idx2, 
04272                     unsigned bit_idx3) 
04273     { 
04274         bp_[0]=(B)(bit_idx0+base_idx_);bp_[1]=(B)(bit_idx1+base_idx_);
04275         bp_[2]=(B)(bit_idx2+base_idx_);bp_[3]=(B)(bit_idx3+base_idx_);
04276         bp_+=4;
04277     }
04278 
04279 private:
04280     copy_to_array_functor_inc(const copy_to_array_functor_inc&);
04281     copy_to_array_functor_inc& operator=(const copy_to_array_functor_inc&);
04282 private:
04283     B*        bp_;
04284     unsigned  base_idx_; ///< Base increment factor
04285 };
04286 
04287 
04288 /*!
04289    \brief Unpacks word into list of ON bit indexes (quad-bit based)
04290    \param w - value
04291    \param bits - pointer on the result array 
04292    \return number of bits in the list
04293 
04294    @ingroup bitfunc
04295 */
04296 template<typename T,typename B> unsigned bit_list_4(T w, B* bits)
04297 {
04298     copy_to_array_functor<B> func(bits);
04299     bit_for_each_4(w, func);
04300     return (unsigned)(func.ptr() - bits);
04301 }
04302 
04303 /*!
04304    \brief Unpacks word into list of ON bit indexes
04305    \param w - value
04306    \param bits - pointer on the result array 
04307    \return number of bits in the list
04308 
04309    @ingroup bitfunc
04310 */
04311 template<typename T,typename B> unsigned bit_list(T w, B* bits)
04312 {
04313     copy_to_array_functor<B> func(bits);
04314     bit_for_each(w, func);
04315     return (unsigned)(func.ptr() - bits);
04316 }
04317 
04318 
04319 /*!
04320     \brief Convert bit block into an array of ints corresponding to 1 bits
04321     @ingroup bitfunc 
04322 */
04323 template<typename T> T bit_convert_to_arr(T* BMRESTRICT dest, 
04324                                           const unsigned* BMRESTRICT src, 
04325                                           bm::id_t bits, 
04326                                           unsigned dest_len,
04327                                           unsigned mask = 0)
04328 {
04329     T* BMRESTRICT pcurr = dest;
04330     for(unsigned bit_idx=0; bit_idx < bits; ++src,bit_idx += sizeof(*src) * 8)
04331     {
04332         unsigned val = *src ^ mask; // possible to invert value by XOR 0xFF..
04333         if (val == 0) 
04334         {
04335             continue;
04336         }
04337         if (pcurr + sizeof(val)*8 >= dest + dest_len) // insufficient space
04338         {
04339             return 0;
04340         }
04341 
04342         copy_to_array_functor_inc<T> func(pcurr, bit_idx);
04343         bit_for_each_4(val, func);      
04344         unsigned word_bit_cnt = func.ptr() - pcurr;
04345         pcurr += word_bit_cnt;    
04346 
04347     } // for
04348     return (T)(pcurr - dest);
04349 }
04350 
04351 
04352 
04353 
04354 /*!
04355     OBSOLETE function
04356     \brief Convert bit block into an array of ints corresponding to 1 bits
04357     \internal
04358     @ingroup bitfunc 
04359 */
04360 /*
04361 template<typename T> T bit_convert_to_arr2(T* BMRESTRICT dest, 
04362                                           const unsigned* BMRESTRICT src, 
04363                                           bm::id_t bits, 
04364                                           unsigned dest_len)
04365 {
04366     register T* BMRESTRICT pcurr = dest;
04367     T* BMRESTRICT end = dest + dest_len; 
04368     unsigned  bit_idx = 0;
04369 
04370     do
04371     {
04372         register unsigned val = *src;
04373         // We can skip if *src == 0 
04374 
04375         while (val == 0)
04376         {
04377             bit_idx += sizeof(*src) * 8;
04378             if (bit_idx >= bits)
04379             {
04380                return (T)(pcurr - dest);
04381             }
04382             val = *(++src);
04383         }
04384 
04385         if (pcurr + sizeof(val)*8 > end) // insufficient space
04386         {
04387             return 0;
04388         }
04389                 
04390         for (int i = 0; i < 32; i+=4)
04391         {
04392             if (val & 1)
04393                 *pcurr++ = bit_idx;
04394             val >>= 1; ++bit_idx;
04395             if (val & 1)
04396                 *pcurr++ = bit_idx;
04397             val >>= 1; ++bit_idx;
04398             if (val & 1)
04399                 *pcurr++ = bit_idx;
04400             val >>= 1; ++bit_idx;
04401             if (val & 1)
04402                 *pcurr++ = bit_idx;
04403             val >>= 1; ++bit_idx;
04404         }
04405         
04406         if (bits <= bit_idx)
04407             break;
04408 
04409         val = *(++src);
04410     } while (1);
04411 
04412     return (T)(pcurr - dest);
04413 }
04414 */
04415 
04416 
04417 /*! @brief Calculates memory overhead for number of gap blocks sharing 
04418            the same memory allocation table (level lengths table).
04419     @ingroup gapfunc
04420 */
04421 template<typename T> 
04422 unsigned gap_overhead(const T* length, 
04423                       const T* length_end, 
04424                       const T* glevel_len)
04425 {
04426     BM_ASSERT(length && length_end && glevel_len);
04427 
04428     unsigned overhead = 0;
04429     for (;length < length_end; ++length)
04430     {
04431         unsigned len = *length;
04432         int level = gap_calc_level(len, glevel_len);
04433         BM_ASSERT(level >= 0 && level < (int)bm::gap_levels);
04434         unsigned capacity = glevel_len[level];
04435         BM_ASSERT(capacity >= len);
04436         overhead += capacity - len;
04437     }
04438     return overhead;
04439 }
04440 
04441 
04442 /*! @brief Finds optimal gap blocks lengths.
04443     @param length - first element of GAP lengths array
04444     @param length_end - end of the GAP lengths array
04445     @param glevel_len - destination GAP lengths array
04446     @ingroup gapfunc
04447 */
04448 
04449 template<typename T>
04450 bool improve_gap_levels(const T* length,
04451                         const T* length_end,
04452                         T*       glevel_len)
04453 {
04454     BM_ASSERT(length && length_end && glevel_len);
04455 
04456     size_t lsize = length_end - length;
04457 
04458     BM_ASSERT(lsize);
04459     
04460     gap_word_t max_len = 0;
04461     unsigned i;
04462     for (i = 0; i < lsize; ++i)
04463     {
04464         if (length[i] > max_len)
04465             max_len = length[i];
04466     }
04467     if (max_len < 5 || lsize <= bm::gap_levels)
04468     {
04469         glevel_len[0] = max_len + 4;
04470         for (i = 1; i < bm::gap_levels; ++i)
04471         {
04472             glevel_len[i] = bm::gap_max_buff_len;
04473         }
04474         return true;
04475     }
04476 
04477     glevel_len[bm::gap_levels-1] = max_len + 5;
04478 
04479     unsigned min_overhead = gap_overhead(length, length_end, glevel_len);
04480     bool is_improved = false;
04481     gap_word_t prev_value = glevel_len[bm::gap_levels-1];
04482     //
04483     // main problem solving loop
04484     //
04485     for (i = bm::gap_levels-2; ; --i)
04486     {
04487         unsigned opt_len = 0;
04488         unsigned j;
04489         bool imp_flag = false;
04490         gap_word_t gap_saved_value = glevel_len[i];
04491         for (j = 0; j < lsize; ++j)
04492         {
04493 //            if (length[j]+4 > prev_value)
04494 //                continue;
04495             
04496             glevel_len[i] = length[j]+4;
04497             unsigned ov = gap_overhead(length, length_end, glevel_len);
04498             if (ov <= min_overhead)
04499             {
04500                 min_overhead = ov;                
04501                 opt_len = length[j]+4;
04502                 imp_flag = true;
04503             }
04504         }
04505         if (imp_flag) {
04506             glevel_len[i] = opt_len; // length[opt_idx]+4;
04507             is_improved = true;
04508         }
04509         else 
04510         {
04511             glevel_len[i] = gap_saved_value;
04512         }
04513         if (i == 0) 
04514             break;
04515         prev_value = glevel_len[i];
04516     }
04517     // 
04518     // Remove duplicates
04519     //
04520 
04521     T val = *glevel_len;
04522     T* gp = glevel_len;
04523     T* res = glevel_len;
04524     for (i = 0; i < bm::gap_levels; ++i)
04525     {
04526         if (val != *gp)
04527         {
04528             val = *gp;
04529             *++res = val;
04530         }
04531         ++gp;
04532     }
04533 
04534     // Filling the "unused" part with max. possible value
04535     while (++res < (glevel_len + bm::gap_levels)) 
04536     {
04537         *res = bm::gap_max_buff_len;
04538     }
04539 
04540     return is_improved;
04541 
04542 }
04543 
04544 
04545 
04546 /**
04547     Bit-block get adapter, takes bitblock and represents it as a 
04548     get_32() accessor function
04549     /internal
04550 */
04551 class bitblock_get_adapter
04552 {
04553 public:
04554     bitblock_get_adapter(const bm::word_t* bit_block) : b_(bit_block) {}
04555     
04556     BMFORCEINLINE
04557     bm::word_t get_32() { return *b_++; }
04558 private:
04559     const bm::word_t*  b_;
04560 };
04561 
04562 
04563 /**
04564     Bit-block store adapter, takes bitblock and saves results into it
04565     /internal
04566 */
04567 class bitblock_store_adapter
04568 {
04569 public:
04570     bitblock_store_adapter(bm::word_t* bit_block) : b_(bit_block) {}
04571     BMFORCEINLINE
04572     void push_back(bm::word_t w) { *b_++ = w; }
04573 private:
04574     bm::word_t* b_;
04575 };
04576 
04577 /**
04578     Bit-block sum adapter, takes values and sums it
04579     /internal
04580 */
04581 class bitblock_sum_adapter
04582 {
04583 public:
04584     bitblock_sum_adapter() : sum_(0) {}
04585     BMFORCEINLINE
04586     void push_back(bm::word_t w) { this->sum_+= w; }
04587     /// Get accumulated sum
04588     bm::word_t sum() const { return this->sum_; }
04589 private:
04590     bm::word_t sum_;
04591 };
04592 
04593 /**
04594     Adapter to get words from a range stream 
04595     (see range serialized bit-block)
04596     \internal
04597 */
04598 template<class DEC> class decoder_range_adapter
04599 {
04600 public: 
04601     decoder_range_adapter(DEC& dec, unsigned from_idx, unsigned to_idx)
04602     : decoder_(dec),
04603       from_(from_idx),
04604       to_(to_idx),
04605       cnt_(0)
04606     {}
04607 
04608     bm::word_t get_32()
04609     {
04610         if (cnt_ < from_ || cnt_ > to_)
04611         {    
04612             ++cnt_; return 0;
04613         }
04614         ++cnt_;
04615         return decoder_.get_32();
04616     }
04617 
04618 private:
04619     DEC&     decoder_;
04620     unsigned from_;
04621     unsigned to_;
04622     unsigned cnt_;
04623 };
04624 
04625 
04626 /*!
04627     Abstract recombination algorithm for two bit-blocks
04628     Bit blocks can come as dserialization decoders or bit-streams
04629 */
04630 template<class It1, class It2, class BinaryOp, class Encoder>
04631 void bit_recomb(It1& it1, It2& it2, 
04632                 BinaryOp& op, 
04633                 Encoder& enc, 
04634                 unsigned block_size = bm::set_block_size)
04635 {
04636     for (unsigned i = 0; i < block_size; ++i)
04637     {
04638         bm::word_t w1 = it1.get_32();
04639         bm::word_t w2 = it2.get_32();
04640         bm::word_t w = op(w1, w2);
04641         enc.push_back( w );
04642     } // for
04643 }
04644 
04645 /// Bit AND functor
04646 template<typename W> struct bit_AND
04647 {
04648     W operator()(W w1, W w2) { return w1 & w2; }
04649 };
04650 
04651 /// Bit OR functor
04652 template<typename W> struct bit_OR
04653 {
04654     W operator()(W w1, W w2) { return w1 | w2; }
04655 };
04656 
04657 /// Bit SUB functor
04658 template<typename W> struct bit_SUB
04659 {
04660     W operator()(W w1, W w2) { return w1 & ~w2; }
04661 };
04662 
04663 /// Bit XOR functor
04664 template<typename W> struct bit_XOR
04665 {
04666     W operator()(W w1, W w2) { return w1 ^ w2; }
04667 };
04668 
04669 /// Bit ASSIGN functor
04670 template<typename W> struct bit_ASSIGN
04671 {
04672     W operator()(W w1, W w2) { return w2; }
04673 };
04674 
04675 /// Bit COUNT functor
04676 template<typename W> struct bit_COUNT
04677 {
04678     W operator()(W w1, W w2) 
04679     {
04680         w1 = 0;
04681         BM_INCWORD_BITCOUNT(w1, w2);
04682         return w1;
04683     }
04684 };
04685 
04686 /// Bit COUNT AND functor
04687 template<typename W> struct bit_COUNT_AND
04688 {
04689     W operator()(W w1, W w2) 
04690     {
04691         W r = 0;
04692         BM_INCWORD_BITCOUNT(r, w1 & w2);
04693         return r;
04694     }
04695 };
04696 
04697 /// Bit COUNT XOR functor
04698 template<typename W> struct bit_COUNT_XOR
04699 {
04700     W operator()(W w1, W w2) 
04701     {
04702         W r = 0;
04703         BM_INCWORD_BITCOUNT(r, w1 ^ w2);
04704         return r;
04705     }
04706 };
04707 
04708 /// Bit COUNT OR functor
04709 template<typename W> struct bit_COUNT_OR
04710 {
04711     W operator()(W w1, W w2) 
04712     {
04713         W r = 0;
04714         BM_INCWORD_BITCOUNT(r, w1 | w2);
04715         return r;
04716     }
04717 };
04718 
04719 
04720 /// Bit COUNT SUB AB functor
04721 template<typename W> struct bit_COUNT_SUB_AB
04722 {
04723     W operator()(W w1, W w2) 
04724     {
04725         W r = 0;
04726         BM_INCWORD_BITCOUNT(r, w1 & (~w2));
04727         return r;
04728     }
04729 };
04730 
04731 /// Bit SUB BA functor
04732 template<typename W> struct bit_COUNT_SUB_BA
04733 {
04734     W operator()(W w1, W w2) 
04735     {
04736         W r = 0;
04737         BM_INCWORD_BITCOUNT(r, w2 & (~w1));
04738         return r;
04739     }
04740 };
04741 
04742 /// Bit COUNT A functor
04743 template<typename W> struct bit_COUNT_A
04744 {
04745     W operator()(W w1, W w2) 
04746     {
04747         W r = 0;
04748         BM_INCWORD_BITCOUNT(r, w1);
04749         return r;
04750     }
04751 };
04752 
04753 /// Bit COUNT B functor
04754 template<typename W> struct bit_COUNT_B
04755 {
04756     W operator()(W w1, W w2) 
04757     {
04758         W r = 0;
04759         BM_INCWORD_BITCOUNT(r, w2);
04760         return r;
04761     }
04762 };
04763 
04764 typedef 
04765 void (*gap_operation_to_bitset_func_type)(unsigned*, 
04766                                           const gap_word_t*);
04767 
04768 typedef 
04769 gap_word_t* (*gap_operation_func_type)(const gap_word_t* BMRESTRICT,
04770                                        const gap_word_t* BMRESTRICT,
04771                                        gap_word_t*       BMRESTRICT,
04772                                        unsigned& );
04773 
04774 typedef
04775 bm::id_t (*bit_operation_count_func_type)(const bm::word_t* BMRESTRICT,
04776                                           const bm::word_t* BMRESTRICT, 
04777                                           const bm::word_t* BMRESTRICT);
04778 
04779 
04780 template<bool T> 
04781 struct operation_functions
04782 {
04783     static 
04784         gap_operation_to_bitset_func_type gap2bit_table_[bm::set_END];
04785     static 
04786         gap_operation_func_type gapop_table_[bm::set_END];
04787     static
04788         bit_operation_count_func_type bit_op_count_table_[bm::set_END];
04789 
04790     static
04791     gap_operation_to_bitset_func_type gap_op_to_bit(unsigned i)
04792     {
04793         return gap2bit_table_[i];
04794     }
04795 
04796     static
04797     gap_operation_func_type gap_operation(unsigned i)
04798     {
04799         return gapop_table_[i];
04800     }
04801 
04802     static
04803     bit_operation_count_func_type bit_operation_count(unsigned i)
04804     {
04805         return bit_op_count_table_[i];
04806     }
04807 };
04808 
04809 template<bool T>
04810 gap_operation_to_bitset_func_type 
04811 operation_functions<T>::gap2bit_table_[bm::set_END] = {
04812     &gap_and_to_bitset<bm::gap_word_t>,    // set_AND
04813     &gap_add_to_bitset<bm::gap_word_t>,    // set_OR
04814     &gap_sub_to_bitset<bm::gap_word_t>,    // set_SUB
04815     &gap_xor_to_bitset<bm::gap_word_t>,    // set_XOR
04816     0
04817 };
04818 
04819 template<bool T>
04820 gap_operation_func_type 
04821 operation_functions<T>::gapop_table_[bm::set_END] = {
04822     &gap_operation_and,    // set_AND
04823     &gap_operation_or,     // set_OR
04824     &gap_operation_sub,    // set_SUB
04825     &gap_operation_xor,    // set_XOR
04826     0
04827 };
04828 
04829 
04830 template<bool T>
04831 bit_operation_count_func_type 
04832 operation_functions<T>::bit_op_count_table_[bm::set_END] = {
04833     0,                            // set_AND
04834     0,                            // set_OR
04835     0,                            // set_SUB
04836     0,                            // set_XOR
04837     0,                            // set_ASSIGN
04838     0,                            // set_COUNT
04839     &bit_operation_and_count,     // set_COUNT_AND
04840     &bit_operation_xor_count,     // set_COUNT_XOR
04841     &bit_operation_or_count,      // set_COUNT_OR
04842     &bit_operation_sub_count,     // set_COUNT_SUB_AB
04843     &bit_operation_sub_count_inv, // set_COUNT_SUB_BA
04844     0,                            // set_COUNT_A
04845     0,                            // set_COUNT_B
04846 };
04847 
04848 } // namespace bm
04849 
04850 #endif
04851 
04852 

Generated on Sun Dec 6 22:15:47 2009 for NCBI C++ ToolKit by  doxygen 1.4.6
Modified on Mon Dec 07 16:20:49 2009 by modify_doxy.py rev. 173732