00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "postgres.h"
00022
00023 #include "access/hash.h"
00024
00025
00026 #define WORDNUM(x) ((x) / BITS_PER_BITMAPWORD)
00027 #define BITNUM(x) ((x) % BITS_PER_BITMAPWORD)
00028
00029 #define BITMAPSET_SIZE(nwords) \
00030 (offsetof(Bitmapset, words) + (nwords) * sizeof(bitmapword))
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #define RIGHTMOST_ONE(x) ((signedbitmapword) (x) & -((signedbitmapword) (x)))
00050
00051 #define HAS_MULTIPLE_ONES(x) ((bitmapword) RIGHTMOST_ONE(x) != (x))
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 static const uint8 rightmost_one_pos[256] = {
00068 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00069 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00070 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00071 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00072 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00073 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00074 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00075 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00076 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00077 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00078 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00079 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00080 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00081 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00082 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00083 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
00084 };
00085
00086 static const uint8 number_of_ones[256] = {
00087 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
00088 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00089 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00090 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00091 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00092 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00093 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00094 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00095 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00096 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00097 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00098 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00099 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00100 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00101 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00102 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
00103 };
00104
00105
00106
00107
00108
00109 Bitmapset *
00110 bms_copy(const Bitmapset *a)
00111 {
00112 Bitmapset *result;
00113 size_t size;
00114
00115 if (a == NULL)
00116 return NULL;
00117 size = BITMAPSET_SIZE(a->nwords);
00118 result = (Bitmapset *) palloc(size);
00119 memcpy(result, a, size);
00120 return result;
00121 }
00122
00123
00124
00125
00126
00127
00128
00129 bool
00130 bms_equal(const Bitmapset *a, const Bitmapset *b)
00131 {
00132 const Bitmapset *shorter;
00133 const Bitmapset *longer;
00134 int shortlen;
00135 int longlen;
00136 int i;
00137
00138
00139 if (a == NULL)
00140 {
00141 if (b == NULL)
00142 return true;
00143 return bms_is_empty(b);
00144 }
00145 else if (b == NULL)
00146 return bms_is_empty(a);
00147
00148 if (a->nwords <= b->nwords)
00149 {
00150 shorter = a;
00151 longer = b;
00152 }
00153 else
00154 {
00155 shorter = b;
00156 longer = a;
00157 }
00158
00159 shortlen = shorter->nwords;
00160 for (i = 0; i < shortlen; i++)
00161 {
00162 if (shorter->words[i] != longer->words[i])
00163 return false;
00164 }
00165 longlen = longer->nwords;
00166 for (; i < longlen; i++)
00167 {
00168 if (longer->words[i] != 0)
00169 return false;
00170 }
00171 return true;
00172 }
00173
00174
00175
00176
00177 Bitmapset *
00178 bms_make_singleton(int x)
00179 {
00180 Bitmapset *result;
00181 int wordnum,
00182 bitnum;
00183
00184 if (x < 0)
00185 elog(ERROR, "negative bitmapset member not allowed");
00186 wordnum = WORDNUM(x);
00187 bitnum = BITNUM(x);
00188 result = (Bitmapset *) palloc0(BITMAPSET_SIZE(wordnum + 1));
00189 result->nwords = wordnum + 1;
00190 result->words[wordnum] = ((bitmapword) 1 << bitnum);
00191 return result;
00192 }
00193
00194
00195
00196
00197
00198
00199 void
00200 bms_free(Bitmapset *a)
00201 {
00202 if (a)
00203 pfree(a);
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 Bitmapset *
00217 bms_union(const Bitmapset *a, const Bitmapset *b)
00218 {
00219 Bitmapset *result;
00220 const Bitmapset *other;
00221 int otherlen;
00222 int i;
00223
00224
00225 if (a == NULL)
00226 return bms_copy(b);
00227 if (b == NULL)
00228 return bms_copy(a);
00229
00230 if (a->nwords <= b->nwords)
00231 {
00232 result = bms_copy(b);
00233 other = a;
00234 }
00235 else
00236 {
00237 result = bms_copy(a);
00238 other = b;
00239 }
00240
00241 otherlen = other->nwords;
00242 for (i = 0; i < otherlen; i++)
00243 result->words[i] |= other->words[i];
00244 return result;
00245 }
00246
00247
00248
00249
00250 Bitmapset *
00251 bms_intersect(const Bitmapset *a, const Bitmapset *b)
00252 {
00253 Bitmapset *result;
00254 const Bitmapset *other;
00255 int resultlen;
00256 int i;
00257
00258
00259 if (a == NULL || b == NULL)
00260 return NULL;
00261
00262 if (a->nwords <= b->nwords)
00263 {
00264 result = bms_copy(a);
00265 other = b;
00266 }
00267 else
00268 {
00269 result = bms_copy(b);
00270 other = a;
00271 }
00272
00273 resultlen = result->nwords;
00274 for (i = 0; i < resultlen; i++)
00275 result->words[i] &= other->words[i];
00276 return result;
00277 }
00278
00279
00280
00281
00282 Bitmapset *
00283 bms_difference(const Bitmapset *a, const Bitmapset *b)
00284 {
00285 Bitmapset *result;
00286 int shortlen;
00287 int i;
00288
00289
00290 if (a == NULL)
00291 return NULL;
00292 if (b == NULL)
00293 return bms_copy(a);
00294
00295 result = bms_copy(a);
00296
00297 shortlen = Min(a->nwords, b->nwords);
00298 for (i = 0; i < shortlen; i++)
00299 result->words[i] &= ~b->words[i];
00300 return result;
00301 }
00302
00303
00304
00305
00306 bool
00307 bms_is_subset(const Bitmapset *a, const Bitmapset *b)
00308 {
00309 int shortlen;
00310 int longlen;
00311 int i;
00312
00313
00314 if (a == NULL)
00315 return true;
00316 if (b == NULL)
00317 return bms_is_empty(a);
00318
00319 shortlen = Min(a->nwords, b->nwords);
00320 for (i = 0; i < shortlen; i++)
00321 {
00322 if ((a->words[i] & ~b->words[i]) != 0)
00323 return false;
00324 }
00325
00326 if (a->nwords > b->nwords)
00327 {
00328 longlen = a->nwords;
00329 for (; i < longlen; i++)
00330 {
00331 if (a->words[i] != 0)
00332 return false;
00333 }
00334 }
00335 return true;
00336 }
00337
00338
00339
00340
00341
00342
00343 BMS_Comparison
00344 bms_subset_compare(const Bitmapset *a, const Bitmapset *b)
00345 {
00346 BMS_Comparison result;
00347 int shortlen;
00348 int longlen;
00349 int i;
00350
00351
00352 if (a == NULL)
00353 {
00354 if (b == NULL)
00355 return BMS_EQUAL;
00356 return bms_is_empty(b) ? BMS_EQUAL : BMS_SUBSET1;
00357 }
00358 if (b == NULL)
00359 return bms_is_empty(a) ? BMS_EQUAL : BMS_SUBSET2;
00360
00361 result = BMS_EQUAL;
00362 shortlen = Min(a->nwords, b->nwords);
00363 for (i = 0; i < shortlen; i++)
00364 {
00365 bitmapword aword = a->words[i];
00366 bitmapword bword = b->words[i];
00367
00368 if ((aword & ~bword) != 0)
00369 {
00370
00371 if (result == BMS_SUBSET1)
00372 return BMS_DIFFERENT;
00373 result = BMS_SUBSET2;
00374 }
00375 if ((bword & ~aword) != 0)
00376 {
00377
00378 if (result == BMS_SUBSET2)
00379 return BMS_DIFFERENT;
00380 result = BMS_SUBSET1;
00381 }
00382 }
00383
00384 if (a->nwords > b->nwords)
00385 {
00386 longlen = a->nwords;
00387 for (; i < longlen; i++)
00388 {
00389 if (a->words[i] != 0)
00390 {
00391
00392 if (result == BMS_SUBSET1)
00393 return BMS_DIFFERENT;
00394 result = BMS_SUBSET2;
00395 }
00396 }
00397 }
00398 else if (a->nwords < b->nwords)
00399 {
00400 longlen = b->nwords;
00401 for (; i < longlen; i++)
00402 {
00403 if (b->words[i] != 0)
00404 {
00405
00406 if (result == BMS_SUBSET2)
00407 return BMS_DIFFERENT;
00408 result = BMS_SUBSET1;
00409 }
00410 }
00411 }
00412 return result;
00413 }
00414
00415
00416
00417
00418 bool
00419 bms_is_member(int x, const Bitmapset *a)
00420 {
00421 int wordnum,
00422 bitnum;
00423
00424
00425 if (x < 0)
00426 elog(ERROR, "negative bitmapset member not allowed");
00427 if (a == NULL)
00428 return false;
00429 wordnum = WORDNUM(x);
00430 bitnum = BITNUM(x);
00431 if (wordnum >= a->nwords)
00432 return false;
00433 if ((a->words[wordnum] & ((bitmapword) 1 << bitnum)) != 0)
00434 return true;
00435 return false;
00436 }
00437
00438
00439
00440
00441 bool
00442 bms_overlap(const Bitmapset *a, const Bitmapset *b)
00443 {
00444 int shortlen;
00445 int i;
00446
00447
00448 if (a == NULL || b == NULL)
00449 return false;
00450
00451 shortlen = Min(a->nwords, b->nwords);
00452 for (i = 0; i < shortlen; i++)
00453 {
00454 if ((a->words[i] & b->words[i]) != 0)
00455 return true;
00456 }
00457 return false;
00458 }
00459
00460
00461
00462
00463 bool
00464 bms_nonempty_difference(const Bitmapset *a, const Bitmapset *b)
00465 {
00466 int shortlen;
00467 int i;
00468
00469
00470 if (a == NULL)
00471 return false;
00472 if (b == NULL)
00473 return !bms_is_empty(a);
00474
00475 shortlen = Min(a->nwords, b->nwords);
00476 for (i = 0; i < shortlen; i++)
00477 {
00478 if ((a->words[i] & ~b->words[i]) != 0)
00479 return true;
00480 }
00481
00482 for (; i < a->nwords; i++)
00483 {
00484 if (a->words[i] != 0)
00485 return true;
00486 }
00487 return false;
00488 }
00489
00490
00491
00492
00493
00494
00495 int
00496 bms_singleton_member(const Bitmapset *a)
00497 {
00498 int result = -1;
00499 int nwords;
00500 int wordnum;
00501
00502 if (a == NULL)
00503 elog(ERROR, "bitmapset is empty");
00504 nwords = a->nwords;
00505 for (wordnum = 0; wordnum < nwords; wordnum++)
00506 {
00507 bitmapword w = a->words[wordnum];
00508
00509 if (w != 0)
00510 {
00511 if (result >= 0 || HAS_MULTIPLE_ONES(w))
00512 elog(ERROR, "bitmapset has multiple members");
00513 result = wordnum * BITS_PER_BITMAPWORD;
00514 while ((w & 255) == 0)
00515 {
00516 w >>= 8;
00517 result += 8;
00518 }
00519 result += rightmost_one_pos[w & 255];
00520 }
00521 }
00522 if (result < 0)
00523 elog(ERROR, "bitmapset is empty");
00524 return result;
00525 }
00526
00527
00528
00529
00530 int
00531 bms_num_members(const Bitmapset *a)
00532 {
00533 int result = 0;
00534 int nwords;
00535 int wordnum;
00536
00537 if (a == NULL)
00538 return 0;
00539 nwords = a->nwords;
00540 for (wordnum = 0; wordnum < nwords; wordnum++)
00541 {
00542 bitmapword w = a->words[wordnum];
00543
00544
00545 while (w != 0)
00546 {
00547 result += number_of_ones[w & 255];
00548 w >>= 8;
00549 }
00550 }
00551 return result;
00552 }
00553
00554
00555
00556
00557
00558
00559 BMS_Membership
00560 bms_membership(const Bitmapset *a)
00561 {
00562 BMS_Membership result = BMS_EMPTY_SET;
00563 int nwords;
00564 int wordnum;
00565
00566 if (a == NULL)
00567 return BMS_EMPTY_SET;
00568 nwords = a->nwords;
00569 for (wordnum = 0; wordnum < nwords; wordnum++)
00570 {
00571 bitmapword w = a->words[wordnum];
00572
00573 if (w != 0)
00574 {
00575 if (result != BMS_EMPTY_SET || HAS_MULTIPLE_ONES(w))
00576 return BMS_MULTIPLE;
00577 result = BMS_SINGLETON;
00578 }
00579 }
00580 return result;
00581 }
00582
00583
00584
00585
00586
00587
00588 bool
00589 bms_is_empty(const Bitmapset *a)
00590 {
00591 int nwords;
00592 int wordnum;
00593
00594 if (a == NULL)
00595 return true;
00596 nwords = a->nwords;
00597 for (wordnum = 0; wordnum < nwords; wordnum++)
00598 {
00599 bitmapword w = a->words[wordnum];
00600
00601 if (w != 0)
00602 return false;
00603 }
00604 return true;
00605 }
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623 Bitmapset *
00624 bms_add_member(Bitmapset *a, int x)
00625 {
00626 int wordnum,
00627 bitnum;
00628
00629 if (x < 0)
00630 elog(ERROR, "negative bitmapset member not allowed");
00631 if (a == NULL)
00632 return bms_make_singleton(x);
00633 wordnum = WORDNUM(x);
00634 bitnum = BITNUM(x);
00635 if (wordnum >= a->nwords)
00636 {
00637
00638 Bitmapset *result;
00639 int nwords;
00640 int i;
00641
00642 result = bms_make_singleton(x);
00643 nwords = a->nwords;
00644 for (i = 0; i < nwords; i++)
00645 result->words[i] |= a->words[i];
00646 pfree(a);
00647 return result;
00648 }
00649
00650 a->words[wordnum] |= ((bitmapword) 1 << bitnum);
00651 return a;
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661 Bitmapset *
00662 bms_del_member(Bitmapset *a, int x)
00663 {
00664 int wordnum,
00665 bitnum;
00666
00667 if (x < 0)
00668 elog(ERROR, "negative bitmapset member not allowed");
00669 if (a == NULL)
00670 return NULL;
00671 wordnum = WORDNUM(x);
00672 bitnum = BITNUM(x);
00673 if (wordnum < a->nwords)
00674 a->words[wordnum] &= ~((bitmapword) 1 << bitnum);
00675 return a;
00676 }
00677
00678
00679
00680
00681 Bitmapset *
00682 bms_add_members(Bitmapset *a, const Bitmapset *b)
00683 {
00684 Bitmapset *result;
00685 const Bitmapset *other;
00686 int otherlen;
00687 int i;
00688
00689
00690 if (a == NULL)
00691 return bms_copy(b);
00692 if (b == NULL)
00693 return a;
00694
00695 if (a->nwords < b->nwords)
00696 {
00697 result = bms_copy(b);
00698 other = a;
00699 }
00700 else
00701 {
00702 result = a;
00703 other = b;
00704 }
00705
00706 otherlen = other->nwords;
00707 for (i = 0; i < otherlen; i++)
00708 result->words[i] |= other->words[i];
00709 if (result != a)
00710 pfree(a);
00711 return result;
00712 }
00713
00714
00715
00716
00717 Bitmapset *
00718 bms_int_members(Bitmapset *a, const Bitmapset *b)
00719 {
00720 int shortlen;
00721 int i;
00722
00723
00724 if (a == NULL)
00725 return NULL;
00726 if (b == NULL)
00727 {
00728 pfree(a);
00729 return NULL;
00730 }
00731
00732 shortlen = Min(a->nwords, b->nwords);
00733 for (i = 0; i < shortlen; i++)
00734 a->words[i] &= b->words[i];
00735 for (; i < a->nwords; i++)
00736 a->words[i] = 0;
00737 return a;
00738 }
00739
00740
00741
00742
00743 Bitmapset *
00744 bms_del_members(Bitmapset *a, const Bitmapset *b)
00745 {
00746 int shortlen;
00747 int i;
00748
00749
00750 if (a == NULL)
00751 return NULL;
00752 if (b == NULL)
00753 return a;
00754
00755 shortlen = Min(a->nwords, b->nwords);
00756 for (i = 0; i < shortlen; i++)
00757 a->words[i] &= ~b->words[i];
00758 return a;
00759 }
00760
00761
00762
00763
00764 Bitmapset *
00765 bms_join(Bitmapset *a, Bitmapset *b)
00766 {
00767 Bitmapset *result;
00768 Bitmapset *other;
00769 int otherlen;
00770 int i;
00771
00772
00773 if (a == NULL)
00774 return b;
00775 if (b == NULL)
00776 return a;
00777
00778 if (a->nwords < b->nwords)
00779 {
00780 result = b;
00781 other = a;
00782 }
00783 else
00784 {
00785 result = a;
00786 other = b;
00787 }
00788
00789 otherlen = other->nwords;
00790 for (i = 0; i < otherlen; i++)
00791 result->words[i] |= other->words[i];
00792 if (other != result)
00793 pfree(other);
00794 return result;
00795 }
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 int
00812 bms_first_member(Bitmapset *a)
00813 {
00814 int nwords;
00815 int wordnum;
00816
00817 if (a == NULL)
00818 return -1;
00819 nwords = a->nwords;
00820 for (wordnum = 0; wordnum < nwords; wordnum++)
00821 {
00822 bitmapword w = a->words[wordnum];
00823
00824 if (w != 0)
00825 {
00826 int result;
00827
00828 w = RIGHTMOST_ONE(w);
00829 a->words[wordnum] &= ~w;
00830
00831 result = wordnum * BITS_PER_BITMAPWORD;
00832 while ((w & 255) == 0)
00833 {
00834 w >>= 8;
00835 result += 8;
00836 }
00837 result += rightmost_one_pos[w & 255];
00838 return result;
00839 }
00840 }
00841 return -1;
00842 }
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852 uint32
00853 bms_hash_value(const Bitmapset *a)
00854 {
00855 int lastword;
00856
00857 if (a == NULL)
00858 return 0;
00859 for (lastword = a->nwords; --lastword >= 0;)
00860 {
00861 if (a->words[lastword] != 0)
00862 break;
00863 }
00864 if (lastword < 0)
00865 return 0;
00866 return DatumGetUInt32(hash_any((const unsigned char *) a->words,
00867 (lastword + 1) * sizeof(bitmapword)));
00868 }