00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stdio.h>
00015 #include "postgres.h"
00016 #include "veil_datatypes.h"
00017 #include "veil_funcs.h"
00018
00019
00020
00021
00022
00023
00024 static
00025 uint32 bitmasks[] = {0x00000001, 0x00000002, 0x00000004, 0x00000008,
00026 0x00000010, 0x00000020, 0x00000040, 0x00000080,
00027 0x00000100, 0x00000200, 0x00000400, 0x00000800,
00028 0x00001000, 0x00002000, 0x00004000, 0x00008000,
00029 0x00010000, 0x00020000, 0x00040000, 0x00080000,
00030 0x00100000, 0x00200000, 0x00400000, 0x00800000,
00031 0x01000000, 0x02000000, 0x04000000, 0x08000000,
00032 0x10000000, 0x20000000, 0x40000000, 0x80000000};
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #define BITZERO(x) (x & 0xffffffe0)
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #define BITMAX(x) (x | 0x1f)
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #define BITSET_ELEM(x) (x >> 5)
00067
00068
00069
00070
00071
00072
00073
00074
00075 #define BITSET_BIT(x) (x & 0x1f)
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 #define ARRAYELEMS(min,max) (((max - BITZERO(min)) >> 5) + 1)
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 #define MIN(a,b) ((a < b)? a: b)
00099
00100
00101
00102
00103
00104
00105
00106 void
00107 vl_ClearBitmap(Bitmap *bitmap)
00108 {
00109 int elems = ARRAYELEMS(bitmap->bitzero, bitmap->bitmax);
00110 int i;
00111
00112 for (i = 0; i < elems; i++) {
00113 bitmap->bitset[i] = 0;
00114 }
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 void
00129 vl_NewBitmap(Bitmap **p_bitmap, bool shared,
00130 int32 min, int32 max)
00131 {
00132 Bitmap *bitmap = *p_bitmap;
00133 int elems = ARRAYELEMS(min, max);
00134
00135 if (bitmap) {
00136 int cur_elems = ARRAYELEMS(bitmap->bitzero, bitmap->bitmax);
00137
00138
00139
00140
00141 if (elems <= cur_elems) {
00142 vl_ClearBitmap(bitmap);
00143 }
00144 else {
00145 if (shared) {
00146 vl_free(bitmap);
00147 }
00148 else {
00149 pfree(bitmap);
00150 }
00151 bitmap = NULL;
00152 }
00153 }
00154 if (!bitmap) {
00155
00156 if (shared) {
00157 bitmap = vl_shmalloc(sizeof(Bitmap) + (sizeof(int32) * elems));
00158 }
00159 else {
00160 bitmap = vl_malloc(sizeof(Bitmap) + (sizeof(int32) * elems));
00161 }
00162 }
00163
00164 DBG_SET_CANARY(*bitmap);
00165 DBG_SET_ELEMS(*bitmap, elems);
00166 DBG_SET_TRAILER(*bitmap, bitset);
00167 bitmap->type = OBJ_BITMAP;
00168 bitmap->bitzero = min;
00169 bitmap->bitmax = max;
00170 vl_ClearBitmap(bitmap);
00171
00172 DBG_TEST_CANARY(*bitmap);
00173 DBG_TEST_TRAILER(*bitmap, bitset);
00174 *p_bitmap = bitmap;
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184 void
00185 vl_BitmapSetbit(Bitmap *bitmap,
00186 int32 bit)
00187 {
00188 int relative_bit = bit - BITZERO(bitmap->bitzero);
00189 int element = BITSET_ELEM(relative_bit);
00190
00191 if ((bit > bitmap->bitmax) ||
00192 (bit < bitmap->bitzero))
00193 {
00194 ereport(ERROR,
00195 (errcode(ERRCODE_INTERNAL_ERROR),
00196 errmsg("Bitmap range error"),
00197 errdetail("Bit (%d) not in range %d..%d. ", bit,
00198 bitmap->bitzero, bitmap->bitmax)));
00199 }
00200
00201 DBG_CHECK_INDEX(*bitmap, element);
00202 bitmap->bitset[element] |= bitmasks[BITSET_BIT(relative_bit)];
00203 DBG_TEST_CANARY(*bitmap);
00204 DBG_TEST_TRAILER(*bitmap, bitset);
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214 void
00215 vl_BitmapClearbit(Bitmap *bitmap,
00216 int32 bit)
00217 {
00218 int relative_bit = bit - BITZERO(bitmap->bitzero);
00219 int element = BITSET_ELEM(relative_bit);
00220
00221 if ((bit > bitmap->bitmax) ||
00222 (bit < bitmap->bitzero))
00223 {
00224 ereport(ERROR,
00225 (errcode(ERRCODE_INTERNAL_ERROR),
00226 errmsg("Bitmap range error"),
00227 errdetail("Bit (%d) not in range %d..%d. ", bit,
00228 bitmap->bitzero, bitmap->bitmax)));
00229 }
00230
00231 bitmap->bitset[element] &= ~(bitmasks[BITSET_BIT(relative_bit)]);
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 bool
00244 vl_BitmapTestbit(Bitmap *bitmap,
00245 int32 bit)
00246 {
00247 int relative_bit = bit - BITZERO(bitmap->bitzero);
00248 int element = BITSET_ELEM(relative_bit);
00249
00250 if ((bit > bitmap->bitmax) ||
00251 (bit < bitmap->bitzero))
00252 {
00253 return false;
00254 }
00255
00256 return (bitmap->bitset[element] & bitmasks[BITSET_BIT(relative_bit)]) != 0;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265 void
00266 vl_BitmapUnion(Bitmap *target,
00267 Bitmap *source)
00268 {
00269 int i;
00270 int elems = ARRAYELEMS(target->bitzero, target->bitmax);
00271
00272
00273 if ((target->bitzero != source->bitzero) ||
00274 (target->bitmax != source->bitmax))
00275 {
00276 ereport(ERROR,
00277 (errcode(ERRCODE_INTERNAL_ERROR),
00278 errmsg("Incompatible bitmaps"),
00279 errdetail("Target range is %d..%d. Source range %d..%d.",
00280 target->bitzero, target->bitmax,
00281 source->bitzero, source->bitmax)));
00282 }
00283 for (i = 0; i < elems; i++) {
00284 target->bitset[i] |= source->bitset[i];
00285 }
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295 void
00296 vl_BitmapIntersect(Bitmap *target,
00297 Bitmap *source)
00298 {
00299 int i;
00300 int elems = ARRAYELEMS(target->bitzero, target->bitmax);
00301
00302
00303 if ((target->bitzero != source->bitzero) ||
00304 (target->bitmax != source->bitmax))
00305 {
00306 ereport(ERROR,
00307 (errcode(ERRCODE_INTERNAL_ERROR),
00308 errmsg("Incompatible bitmaps"),
00309 errdetail("Target range is %d..%d. Source range %d..%d.",
00310 target->bitzero, target->bitmax,
00311 source->bitzero, source->bitmax)));
00312 }
00313 for (i = 0; i < elems; i++) {
00314 target->bitset[i] &= source->bitset[i];
00315 }
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 int32
00329 vl_BitmapNextBit(Bitmap *bitmap,
00330 int32 bit,
00331 bool *found)
00332 {
00333 while (bit <= bitmap->bitmax) {
00334 if (vl_BitmapTestbit(bitmap, bit)) {
00335 *found = true;
00336 return bit;
00337 }
00338 bit++;
00339 }
00340 *found = false;
00341 return 0;
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 Bitmap *
00355 vl_BitmapFromArray(BitmapArray *bmarray,
00356 int32 elem)
00357 {
00358 DBG_TEST_CANARY(*bmarray);
00359 DBG_TEST_TRAILER(*bmarray, bitmap);
00360 if ((elem < bmarray->arrayzero) || (elem > bmarray->arraymax)) {
00361 return NULL;
00362 }
00363 else {
00364 DBG_CHECK_INDEX(*bmarray, elem - bmarray->arrayzero);
00365 return bmarray->bitmap[elem - bmarray->arrayzero];
00366 }
00367 }
00368
00369
00370
00371
00372
00373
00374 void
00375 vl_ClearBitmapArray(BitmapArray *bmarray)
00376 {
00377 int bitmaps = bmarray->arraymax + 1 - bmarray->arrayzero;
00378 int i;
00379
00380 DBG_TEST_CANARY(*bmarray);
00381 DBG_TEST_TRAILER(*bmarray, bitmap);
00382 for (i = 0; i < bitmaps; i++) {
00383 DBG_CHECK_INDEX(*bmarray, i);
00384 vl_ClearBitmap(bmarray->bitmap[i]);
00385 }
00386 }
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 void
00402 vl_NewBitmapArray(BitmapArray **p_bmarray, bool shared,
00403 int32 arrayzero, int32 arraymax,
00404 int32 bitzero, int32 bitmax)
00405 {
00406 BitmapArray *bmarray = *p_bmarray;
00407 int bitsetelems = ARRAYELEMS(bitzero, bitmax);
00408 int bitmaps = arraymax + 1 - arrayzero;
00409 int i;
00410
00411 if (bmarray) {
00412
00413 int cur_elems = ARRAYELEMS(bmarray->bitzero, bmarray->bitmax);
00414 int cur_maps = bmarray->arraymax + 1 - bmarray->arrayzero;
00415
00416 DBG_TEST_CANARY(*bmarray);
00417 DBG_TEST_TRAILER(*bmarray, bitmap);
00418 if ((cur_elems >= bitsetelems) && (cur_maps >= bitmaps)) {
00419 vl_ClearBitmapArray(bmarray);
00420 }
00421 else {
00422 if (shared) {
00423 for (i = 0; i < cur_maps; i++) {
00424 vl_free(bmarray->bitmap[i]);
00425 }
00426 vl_free(bmarray);
00427 }
00428 else {
00429 for (i = 0; i < cur_maps; i++) {
00430 pfree(bmarray->bitmap[i]);
00431 }
00432 pfree(bmarray);
00433 }
00434 bmarray = NULL;
00435 }
00436 }
00437
00438 if (!bmarray) {
00439 if (shared) {
00440 bmarray = vl_shmalloc(sizeof(BitmapArray) +
00441 (sizeof(Bitmap *) * bitmaps));
00442
00443 }
00444 else {
00445 bmarray = vl_malloc(sizeof(BitmapArray) +
00446 (sizeof(Bitmap *) * bitmaps));
00447 }
00448
00449 for (i = 0; i < bitmaps; i++) {
00450 bmarray->bitmap[i] = NULL;
00451 vl_NewBitmap(&(bmarray->bitmap[i]), shared, bitzero, bitmax);
00452 }
00453
00454 bmarray->type = OBJ_BITMAP_ARRAY;
00455 DBG_SET_CANARY(*bmarray);
00456 DBG_SET_ELEMS(*bmarray, bitmaps);
00457 DBG_SET_TRAILER(*bmarray, bitmap);
00458 }
00459 bmarray->bitzero = bitzero;
00460 bmarray->bitmax = bitmax;
00461 bmarray->arrayzero = arrayzero;
00462 bmarray->arraymax = arraymax;
00463
00464 for (i = 0; i < bitmaps; i++) {
00465 bmarray->bitmap[i]->type = OBJ_BITMAP;
00466 bmarray->bitmap[i]->bitzero = bitzero;
00467 bmarray->bitmap[i]->bitmax = bitmax;
00468 }
00469
00470 *p_bmarray = bmarray;
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 static HTAB *
00483 new_hash(char *name)
00484 {
00485 char vl_name[HASH_KEYLEN];
00486 HTAB *hash;
00487 HASHCTL hashctl;
00488
00489 (void) snprintf(vl_name, HASH_KEYLEN - 1, "vl_%s", name);
00490
00491 hashctl.keysize = HASH_KEYLEN;
00492 hashctl.entrysize = sizeof(VarEntry);
00493
00494 hash = hash_create(vl_name, 200, &hashctl, HASH_ELEM);
00495 return hash;
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 VarEntry *
00508 vl_NextHashEntry(HTAB *hash,
00509 VarEntry *prev)
00510 {
00511 VarEntry *next;
00512 static HASH_SEQ_STATUS status;
00513 if (!prev) {
00514
00515
00516 hash_seq_init(&status, hash);
00517 }
00518 next = (VarEntry *) hash_seq_search(&status);
00519 return (next);
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532 void
00533 vl_NewBitmapHash(BitmapHash **p_bmhash, char *name,
00534 int32 bitzero, int32 bitmax)
00535 {
00536 BitmapHash *bmhash = *p_bmhash;
00537
00538 if (bmhash) {
00539 VarEntry *entry = NULL;
00540 HTAB *hash = bmhash->hash;
00541 bool found;
00542
00543 while ((entry = vl_NextHashEntry(hash, entry))) {
00544 if (entry->obj) {
00545 if (entry->obj->type != OBJ_BITMAP) {
00546 ereport(ERROR,
00547 (errcode(ERRCODE_INTERNAL_ERROR),
00548 errmsg("Bitmap hash contains invalid object %d",
00549 entry->obj->type),
00550 errdetail("Object type is %d, expected is %d.",
00551 entry->obj->type, OBJ_BITMAP)));
00552 }
00553 pfree(entry->obj);
00554 }
00555
00556 (void) hash_search(hash, entry->key, HASH_REMOVE, &found);
00557 }
00558 }
00559 else {
00560 bmhash = vl_malloc(sizeof(BitmapHash));
00561 bmhash->type = OBJ_BITMAP_HASH;
00562 bmhash->hash = new_hash(name);
00563 }
00564 bmhash->bitzero = bitzero;
00565 bmhash->bitmax = bitmax;
00566
00567 *p_bmhash = bmhash;
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 Bitmap *
00582 vl_BitmapFromHash(BitmapHash *bmhash,
00583 char *hashelem)
00584 {
00585 VarEntry *var;
00586 Bitmap *bitmap;
00587 bool found;
00588
00589 var = hash_search(bmhash->hash, hashelem, HASH_FIND, &found);
00590 if (!found) {
00591 return NULL;
00592 }
00593
00594 if (!var->obj) {
00595 ereport(ERROR,
00596 (errcode(ERRCODE_INTERNAL_ERROR),
00597 errmsg("BitmapFromHash - empty VarEntry")));
00598 }
00599
00600 if (var->obj->type != OBJ_BITMAP) {
00601 ereport(ERROR,
00602 (errcode(ERRCODE_INTERNAL_ERROR),
00603 errmsg("Bitmap hash contains invalid object %d",
00604 var->obj->type),
00605 errdetail("Object type is %d, expected is %d.",
00606 var->obj->type, OBJ_BITMAP)));
00607 }
00608
00609 bitmap = (Bitmap *) var->obj;
00610 return bitmap;
00611 }
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 Bitmap *
00622 vl_AddBitmapToHash(BitmapHash *bmhash,
00623 char *hashelem)
00624 {
00625 VarEntry *var;
00626 Bitmap *bitmap = NULL;
00627 bool found;
00628
00629 var = hash_search(bmhash->hash, hashelem, HASH_ENTER, &found);
00630 if (found) {
00631 if (!var->obj) {
00632 ereport(ERROR,
00633 (errcode(ERRCODE_INTERNAL_ERROR),
00634 errmsg("AddBitmapToHash - empty VarEntry")));
00635 }
00636 if (var->obj->type != OBJ_BITMAP) {
00637 ereport(ERROR,
00638 (errcode(ERRCODE_INTERNAL_ERROR),
00639 errmsg("AddBitmapToHash - type mismatch %d",
00640 var->obj->type),
00641 errdetail("Object type is %d, expected is %d.",
00642 var->obj->type, OBJ_BITMAP)));
00643 }
00644 return (Bitmap *) var->obj;
00645 }
00646
00647
00648
00649 vl_NewBitmap(&bitmap, FALSE, bmhash->bitzero, bmhash->bitmax);
00650 var->obj = (Object *) bitmap;
00651 return bitmap;
00652 }