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