00001 #ifndef BMFUNC__H__INCLUDED__
00002 #define BMFUNC__H__INCLUDED__
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #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
00045
00046
00047
00048 struct bv_statistics
00049 {
00050
00051 unsigned bit_blocks;
00052
00053 unsigned gap_blocks;
00054
00055 unsigned max_serialize_mem;
00056
00057 unsigned memory_used;
00058
00059 gap_word_t gap_length[bm::set_total_blocks];
00060
00061 gap_word_t gap_levels[bm::gap_levels];
00062
00063
00064
00065
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
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
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
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
00113
00114
00115
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
00131
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
00162
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
00189
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
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
00230 inline
00231 bool is_const_set_operation(set_operation op)
00232 {
00233 return (int(op) >= int(set_COUNT));
00234 }
00235
00236
00237
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
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
00264
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
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
00299
00300
00301
00302
00303
00304
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
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
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
00344
00345
00346
00347
00348
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
00361
00362 enum ByteOrder
00363 {
00364 BigEndian = 0,
00365 LittleEndian = 1
00366 };
00367
00368
00369
00370
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);
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
00419
00420
00421
00422
00423
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
00449
00450
00451
00452
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
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
00514 non_empty_top += (blk_blk[j] != 0);
00515 }
00516 else
00517 {
00518 f.on_empty_block(block_idx);
00519 }
00520 }
00521 if (non_empty_top == 0)
00522 {
00523 f.on_empty_top(i);
00524 }
00525 }
00526 }
00527
00528
00529
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
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
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
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
00613
00614
00615
00616
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;
00635
00636 while (pcurr <= pend)
00637 {
00638 bits_counter += *pcurr - *(pcurr-1);
00639 pcurr += 2;
00640 }
00641
00642 return bits_counter;
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
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)
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
00694
00695
00696
00697
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);
00709 ++pcurr;
00710 do
00711 {
00712 func(*pcurr - prev);
00713 prev = *pcurr;
00714 } while (++pcurr < pend);
00715 }
00716
00717
00718
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
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
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)
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
00756
00757
00758
00759
00760
00761
00762
00763
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)
00771 {
00772 len = *pcurr >> 3;
00773 *gap_buf++ = *pcurr++;
00774 }
00775 else
00776 {
00777 len = gap_header >> 3;
00778 *gap_buf++ = gap_header;
00779 }
00780 --len;
00781 register const T* pend = pcurr + len;
00782
00783 *gap_buf = *pcurr++;
00784 if (*gap_buf == 0)
00785 *gap_buf = 65535;
00786 else
00787 *gap_buf = *gap_buf - 1;
00788
00789 for (++gap_buf; pcurr < pend; ++pcurr)
00790 {
00791 T prev = *(gap_buf-1);
00792 *gap_buf++ = *pcurr + prev;
00793 }
00794 *gap_buf = 65535;
00795 }
00796
00797
00798
00799
00800
00801
00802
00803
00804
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
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
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
00899
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
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 }
00934
00935 dlen = (unsigned)(res - dest);
00936 *dest = (*dest & 7) + (dlen << 3);
00937
00938 }
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
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
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 }
01007
01008 return 0;
01009 }
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
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
01119
01120 if (pos == 0)
01121 {
01122 *buf ^= 1;
01123 if ( buf[1] )
01124 {
01125 ::memmove(&buf[2], &buf[1], (end - 1) * sizeof(gap_word_t));
01126 buf[1] = 0;
01127 ++end;
01128 }
01129 else
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)
01141 {
01142 ++(*pprev);
01143 if (*pprev == *pcurr)
01144 {
01145 --end;
01146 if (pcurr != pend)
01147 {
01148 --end;
01149 ++pcurr;
01150 do
01151 {
01152 *pprev++ = *pcurr++;
01153 } while (pcurr < pend);
01154 }
01155 }
01156 }
01157 else if (*pcurr == pos)
01158 {
01159 --(*pcurr);
01160 if (pcurr == pend)
01161 {
01162 ++end;
01163 }
01164 }
01165 else
01166 {
01167 ::memmove(pcurr+2, pcurr,(end - curr + 1)*sizeof(T));
01168 *pcurr++ = pos - 1;
01169 *pcurr = pos;
01170 end+=2;
01171 }
01172
01173
01174 *buf = (*buf & 7) + (end << 3);
01175
01176 buf[end] = bm::gap_max_bits - 1;
01177 return end;
01178 }
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
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)
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);
01208 }
01209
01210
01211
01212
01213
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
01225
01226
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
01239
01240
01241
01242
01243
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)
01256 {
01257 *word |= unsigned(1 << nbit);
01258 return;
01259 }
01260
01261 if (nbit)
01262 {
01263 unsigned right_margin = nbit + bitcount;
01264
01265
01266
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;
01275 }
01276 else
01277 {
01278 *word |= block_set_table<true>::_right[nbit];
01279 bitcount -= 32 - nbit;
01280 }
01281 ++word;
01282 }
01283
01284
01285
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
01301
01302
01303
01304
01305
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)
01318 {
01319 *word &= ~unsigned(1 << nbit);
01320 return;
01321 }
01322
01323 if (nbit)
01324 {
01325 unsigned right_margin = nbit + bitcount;
01326
01327
01328
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;
01337 }
01338 else
01339 {
01340 *word &= ~block_set_table<true>::_right[nbit];
01341 bitcount -= 32 - nbit;
01342 }
01343 ++word;
01344 }
01345
01346
01347
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
01363
01364
01365
01366
01367
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)
01380 {
01381 *word ^= unsigned(1 << nbit);
01382 return;
01383 }
01384
01385 if (nbit)
01386 {
01387 unsigned right_margin = nbit + bitcount;
01388
01389
01390
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;
01399 }
01400 else
01401 {
01402 *word ^= block_set_table<true>::_right[nbit];
01403 bitcount -= 32 - nbit;
01404 }
01405 ++word;
01406 }
01407
01408
01409
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
01425
01426
01427
01428
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)
01438 {
01439 sub_bit_block(dest, 0, *pcurr + 1);
01440 ++pcurr;
01441 }
01442 ++pcurr;
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
01457
01458
01459
01460
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)
01470 {
01471 xor_bit_block(dest, 0, *pcurr + 1);
01472 ++pcurr;
01473 }
01474 ++pcurr;
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
01489
01490
01491
01492
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)
01502 {
01503 or_bit_block(dest, 0, *pcurr + 1);
01504 ++pcurr;
01505 }
01506 ++pcurr;
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
01521
01522
01523
01524
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) )
01534 {
01535
01536 sub_bit_block(dest, 0, *pcurr + 1);
01537 ++pcurr;
01538 }
01539 ++pcurr;
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
01554
01555
01556
01557
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)
01571 {
01572 count += bit_block_calc_count_range(block, 0, *pcurr);
01573 ++pcurr;
01574 }
01575 ++pcurr;
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
01590
01591
01592
01593
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)
01606 {
01607 count += bit_block_any_range(block, 0, *pcurr);
01608 if (count)
01609 return count;
01610 ++pcurr;
01611 }
01612 ++pcurr;
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
01629
01630
01631
01632
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))
01646 {
01647 count += bit_block_calc_count_range(block, 0, *pcurr);
01648 ++pcurr;
01649 }
01650 ++pcurr;
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
01662
01663
01664
01665
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))
01679 {
01680 count += bit_block_any_range(block, 0, *pcurr);
01681 if (count)
01682 return count;
01683 ++pcurr;
01684 }
01685 ++pcurr;
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
01700
01701
01702
01703
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)
01728 {
01729 c = (*pcurr - prev + 1) - c;
01730 }
01731 count += c;
01732 }
01733 return count;
01734 }
01735
01736
01737
01738
01739
01740
01741
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)
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
01781
01782
01783
01784
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
01828
01829
01830
01831
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
01878
01879
01880
01881
01882
01883
01884 inline
01885 void bit_block_set(bm::word_t* BMRESTRICT dst, bm::word_t value)
01886 {
01887
01888
01889
01890 ::memset(dst, value, bm::set_block_size * sizeof(bm::word_t));
01891
01892 }
01893
01894
01895
01896
01897
01898
01899
01900
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
01912
01913
01914
01915
01916
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
01929
01930
01931
01932
01933
01934
01935
01936
01937
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
01956
01957
01958
01959
01960
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)
01971 {
01972 ++pcurr;
01973 }
01974 ++pcurr;
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
01988
01989
01990
01991
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
02005
02006
02007
02008
02009
02010
02011
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
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
02060
02061
02062
02063
02064 template<typename T> void gap_invert(T* buf)
02065 {
02066 *buf ^= 1;
02067 }
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
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
02103
02104
02105
02106
02107
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
02117
02118
02119
02120
02121
02122 template<typename T> unsigned gap_length(const T* buf)
02123 {
02124 return (*buf >> 3) + 1;
02125 }
02126
02127
02128
02129
02130
02131
02132
02133
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
02144
02145
02146
02147
02148
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
02159
02160
02161
02162
02163
02164 template<typename T> unsigned gap_level(const T* buf)
02165 {
02166 return (*buf >> 1) & 3;
02167 }
02168
02169
02170
02171
02172
02173
02174
02175
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
02187
02188
02189
02190
02191
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
02206
02207
02208
02209
02210
02211
02212
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
02225
02226
02227
02228
02229
02230
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
02256
02257
02258
02259
02260
02261
02262
02263
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
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
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;
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
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;
02325 }
02326 }
02327
02328 mask <<= 1;
02329 ++bit_idx;
02330
02331 }
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
02353
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;
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;
02403 }
02404 }
02405
02406
02407
02408
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;
02425
02426 if (bitval)
02427 {
02428 if (unsigned(*pcurr + 1) >= dest_len)
02429 return 0;
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;
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;
02455 }
02456 return (D) (dest_curr - dest);
02457 }
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
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
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++;
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)
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);
02505
02506 #else
02507
02508
02509
02510
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)
02518 {
02519 BM_INCWORD_BITCOUNT(count, acc);
02520 acc = acc_prev;
02521 }
02522 } while (block < block_end);
02523
02524 BM_INCWORD_BITCOUNT(count, acc);
02525
02526 #endif
02527
02528 return count;
02529 }
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
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
02559
02560
02561
02562
02563
02564
02565
02566
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
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));
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);
02630 count -= !(w_prev ^ w_l);
02631
02632 w_prev = (w0 >> w_shift);
02633 }
02634 }
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));
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);
02668 count -= !(w_prev ^ w_l);
02669
02670 w_prev = (w0 >> w_shift);
02671 }
02672 }
02673 #endif
02674 return count;
02675 #endif
02676 }
02677
02678
02679
02680
02681
02682
02683
02684
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;
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)
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)
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
02732 for ( ;bitcount >= 32; bitcount -= 32)
02733 {
02734 acc = *word++;
02735 BM_INCWORD_BITCOUNT(count, acc);
02736 }
02737
02738 if (bitcount)
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
02750
02751
02752
02753
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;
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)
02769 {
02770 return (*word >> nbit) & 1;
02771 }
02772 unsigned acc;
02773 unsigned bitcount = right - left + 1;
02774
02775 if (nbit)
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
02797 for ( ;bitcount >= 32; bitcount -= 32)
02798 {
02799 acc = *word++;
02800 if (acc)
02801 return acc;
02802 }
02803
02804 if (bitcount)
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
02819
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
02840
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
02861
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
02881
02882
02883 inline unsigned and_op(unsigned v1, unsigned v2)
02884 {
02885 return v1 & v2;
02886 }
02887
02888
02889
02890 inline unsigned xor_op(unsigned v1, unsigned v2)
02891 {
02892 return v1 ^ v2;
02893 }
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
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
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
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
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
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
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
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
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
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
03023
03024
03025
03026
03027
03028
03029
03030
03031
03032
03033
03034
03035
03036
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
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
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
03072
03073
03074
03075
03076
03077
03078
03079
03080
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
03095
03096
03097
03098
03099
03100
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
03128
03129
03130
03131
03132
03133
03134
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
03163
03164
03165
03166
03167
03168
03169
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
03194
03195
03196
03197
03198
03199
03200
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
03229
03230
03231
03232
03233
03234
03235
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
03260
03261
03262
03263
03264
03265
03266
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
03294
03295
03296
03297
03298
03299
03300
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
03324
03325
03326
03327
03328
03329
03330
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
03358
03359
03360
03361
03362
03363
03364
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
03389
03390
03391
03392
03393
03394
03395
03396
03397
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))
03407 {
03408
03409 if (!IS_VALID_ADDR(src))
03410 {
03411 if (IS_EMPTY_BLOCK(src))
03412 {
03413
03414
03415 return 0;
03416 }
03417 }
03418 else
03419 {
03420
03421 bit_block_and(dst, src);
03422 }
03423 }
03424 else
03425 {
03426 if(!IS_VALID_ADDR(src))
03427 {
03428 if(IS_EMPTY_BLOCK(src))
03429 {
03430
03431
03432 return 0;
03433 }
03434
03435
03436 }
03437 else
03438 {
03439 if (IS_FULL_BLOCK(dst))
03440 {
03441 return const_cast<bm::word_t*>(src);
03442 }
03443
03444
03445 }
03446 }
03447
03448 return ret;
03449 }
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
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
03477
03478
03479
03480
03481
03482
03483
03484
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
03502
03503
03504
03505
03506
03507
03508
03509
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))
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
03531
03532
03533
03534
03535
03536
03537
03538
03539
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
03553
03554
03555
03556
03557
03558
03559
03560
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))
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
03583
03584
03585
03586
03587
03588
03589
03590
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;
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
03615
03616
03617
03618
03619
03620
03621
03622
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;
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
03650
03651
03652
03653
03654
03655
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
03684
03685
03686
03687
03688
03689
03690
03691
03692
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))
03703 {
03704 if (!IS_VALID_ADDR(src))
03705 {
03706 if (IS_FULL_BLOCK(src))
03707 {
03708
03709
03710 ::memset(dst, 0xFF, bm::set_block_size * sizeof(bm::word_t));
03711 }
03712 }
03713 else
03714 {
03715
03716 bit_block_or(dst, src);
03717 }
03718 }
03719 else
03720 {
03721 if (!IS_VALID_ADDR(src))
03722 {
03723 if (IS_FULL_BLOCK(src))
03724 {
03725
03726
03727 return const_cast<bm::word_t*>(FULL_BLOCK_ADDR);
03728 }
03729 }
03730 else
03731 {
03732 if (dst == 0)
03733 {
03734
03735
03736 return const_cast<bm::word_t*>(src);
03737 }
03738 }
03739 }
03740 return ret;
03741 }
03742
03743
03744
03745
03746
03747
03748
03749
03750
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
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
03782
03783
03784
03785
03786
03787
03788
03789
03790
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))
03800 {
03801 if (!IS_VALID_ADDR(src))
03802 {
03803 if (IS_FULL_BLOCK(src))
03804 {
03805
03806
03807 return 0;
03808 }
03809 }
03810 else
03811 {
03812 bit_block_sub(dst, src);
03813 }
03814 }
03815 else
03816 {
03817 if (!IS_VALID_ADDR(src))
03818 {
03819 if (IS_FULL_BLOCK(src))
03820 {
03821
03822 return 0;
03823 }
03824 }
03825 else
03826 {
03827 if (IS_FULL_BLOCK(dst))
03828 {
03829
03830
03831 return const_cast<bm::word_t*>(src);
03832 }
03833 }
03834 }
03835 return ret;
03836 }
03837
03838
03839
03840
03841
03842
03843
03844
03845
03846
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
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
03878
03879
03880
03881
03882
03883
03884
03885
03886
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;
03894
03895 bm::word_t* ret = dst;
03896
03897 if (IS_VALID_ADDR(dst))
03898 {
03899 if (!src) return dst;
03900
03901 bit_block_xor(dst, src);
03902 }
03903 else
03904 {
03905 if (!src) return dst;
03906
03907
03908
03909
03910
03911 return const_cast<bm::word_t*>(src);
03912 }
03913 return ret;
03914 }
03915
03916
03917
03918
03919
03920
03921
03922
03923
03924
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
03943
03944
03945
03946
03947
03948
03949
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
03971
03972
03973
03974
03975
03976
03977
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
03987 const T* blk_end = blk + data_size - 2;
03988
03989
03990
03991 do
03992 {
03993 if (*blk == 0)
03994 {
03995
03996
03997 const T* blk_j = blk + 1;
03998 for (; blk_j < blk_end; ++blk_j)
03999 {
04000 if (*blk_j != 0)
04001 break;
04002 }
04003
04004 blk = blk_j-1;
04005 count += sizeof(gap_word_t);
04006 }
04007 else
04008 {
04009
04010
04011 const T* blk_j = blk + 1;
04012 for ( ; blk_j < blk_end; ++blk_j)
04013 {
04014
04015 if (*blk_j == 0)
04016 {
04017
04018
04019
04020
04021 if (blk_j[1] | blk_j[2])
04022 {
04023
04024
04025 ++blk_j;
04026 continue;
04027 }
04028 break;
04029 }
04030 }
04031 count += sizeof(gap_word_t);
04032
04033 count += (blk_j - blk) * sizeof(T);
04034 blk = blk_j;
04035
04036
04037
04038
04039
04040
04041 }
04042 ++blk;
04043 }
04044 while(blk < blk_end);
04045
04046 return count + (2 * sizeof(T));
04047 }
04048
04049
04050
04051
04052
04053
04054
04055
04056
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
04097
04098
04099
04100
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:
04110 break;
04111 case 1:
04112 func(sub_octet);
04113 break;
04114 case 2:
04115 func(sub_octet + 1);
04116 break;
04117 case 3:
04118 func(sub_octet, sub_octet + 1);
04119 break;
04120 case 4:
04121 func(sub_octet + 2);
04122 break;
04123 case 5:
04124 func(sub_octet, sub_octet + 2);
04125 break;
04126 case 6:
04127 func(sub_octet + 1, sub_octet + 2);
04128 break;
04129 case 7:
04130 func(sub_octet, sub_octet + 1, sub_octet + 2);
04131 break;
04132 case 8:
04133 func(sub_octet + 3);
04134 break;
04135 case 9:
04136 func(sub_octet, sub_octet + 3);
04137 break;
04138 case 10:
04139 func(sub_octet + 1, sub_octet + 3);
04140 break;
04141 case 11:
04142 func(sub_octet, sub_octet + 1, sub_octet + 3);
04143 break;
04144 case 12:
04145 func(sub_octet + 2, sub_octet + 3);
04146 break;
04147 case 13:
04148 func(sub_octet, sub_octet + 2, sub_octet + 3);
04149 break;
04150 case 14:
04151 func(sub_octet + 1, sub_octet + 2, sub_octet + 3);
04152 break;
04153 case 15:
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 }
04162 }
04163
04164
04165
04166
04167
04168
04169
04170
04171
04172 template<typename T, typename F>
04173 void bit_for_each(T w, F& func)
04174 {
04175
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 }
04188 }
04189
04190
04191
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
04236
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_;
04285 };
04286
04287
04288
04289
04290
04291
04292
04293
04294
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
04305
04306
04307
04308
04309
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
04321
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;
04333 if (val == 0)
04334 {
04335 continue;
04336 }
04337 if (pcurr + sizeof(val)*8 >= dest + dest_len)
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 }
04348 return (T)(pcurr - dest);
04349 }
04350
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362
04363
04364
04365
04366
04367
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380
04381
04382
04383
04384
04385
04386
04387
04388
04389
04390
04391
04392
04393
04394
04395
04396
04397
04398
04399
04400
04401
04402
04403
04404
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
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
04443
04444
04445
04446
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
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
04494
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;
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
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
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
04548
04549
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
04565
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
04579
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
04588 bm::word_t sum() const { return this->sum_; }
04589 private:
04590 bm::word_t sum_;
04591 };
04592
04593
04594
04595
04596
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
04628
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 }
04643 }
04644
04645
04646 template<typename W> struct bit_AND
04647 {
04648 W operator()(W w1, W w2) { return w1 & w2; }
04649 };
04650
04651
04652 template<typename W> struct bit_OR
04653 {
04654 W operator()(W w1, W w2) { return w1 | w2; }
04655 };
04656
04657
04658 template<typename W> struct bit_SUB
04659 {
04660 W operator()(W w1, W w2) { return w1 & ~w2; }
04661 };
04662
04663
04664 template<typename W> struct bit_XOR
04665 {
04666 W operator()(W w1, W w2) { return w1 ^ w2; }
04667 };
04668
04669
04670 template<typename W> struct bit_ASSIGN
04671 {
04672 W operator()(W w1, W w2) { return w2; }
04673 };
04674
04675
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
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
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
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
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
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
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
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>,
04813 &gap_add_to_bitset<bm::gap_word_t>,
04814 &gap_sub_to_bitset<bm::gap_word_t>,
04815 &gap_xor_to_bitset<bm::gap_word_t>,
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,
04823 &gap_operation_or,
04824 &gap_operation_sub,
04825 &gap_operation_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,
04834 0,
04835 0,
04836 0,
04837 0,
04838 0,
04839 &bit_operation_and_count,
04840 &bit_operation_xor_count,
04841 &bit_operation_or_count,
04842 &bit_operation_sub_count,
04843 &bit_operation_sub_count_inv,
04844 0,
04845 0,
04846 };
04847
04848 }
04849
04850 #endif
04851
04852