3
#define GETENTRY(vec,pos) ((GISTTYPE *) DatumGetPointer((vec)->vector[(pos)].key))
7
PG_FUNCTION_INFO_V1(g_intbig_consistent);
8
PG_FUNCTION_INFO_V1(g_intbig_compress);
9
PG_FUNCTION_INFO_V1(g_intbig_decompress);
10
PG_FUNCTION_INFO_V1(g_intbig_penalty);
11
PG_FUNCTION_INFO_V1(g_intbig_picksplit);
12
PG_FUNCTION_INFO_V1(g_intbig_union);
13
PG_FUNCTION_INFO_V1(g_intbig_same);
15
Datum g_intbig_consistent(PG_FUNCTION_ARGS);
16
Datum g_intbig_compress(PG_FUNCTION_ARGS);
17
Datum g_intbig_decompress(PG_FUNCTION_ARGS);
18
Datum g_intbig_penalty(PG_FUNCTION_ARGS);
19
Datum g_intbig_picksplit(PG_FUNCTION_ARGS);
20
Datum g_intbig_union(PG_FUNCTION_ARGS);
21
Datum g_intbig_same(PG_FUNCTION_ARGS);
23
#define SUMBIT(val) ( \
24
GETBITBYTE((val),0) + \
25
GETBITBYTE((val),1) + \
26
GETBITBYTE((val),2) + \
27
GETBITBYTE((val),3) + \
28
GETBITBYTE((val),4) + \
29
GETBITBYTE((val),5) + \
30
GETBITBYTE((val),6) + \
34
PG_FUNCTION_INFO_V1(_intbig_in);
35
Datum _intbig_in(PG_FUNCTION_ARGS);
37
PG_FUNCTION_INFO_V1(_intbig_out);
38
Datum _intbig_out(PG_FUNCTION_ARGS);
42
_intbig_in(PG_FUNCTION_ARGS)
45
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
46
errmsg("_intbig_in() not implemented")));
51
_intbig_out(PG_FUNCTION_ARGS)
54
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
55
errmsg("_intbig_out() not implemented")));
60
/*********************************************************************
62
*********************************************************************/
64
_intbig_overlap(GISTTYPE * a, ArrayType *b)
66
int num = ARRNELEMS(b);
67
int4 *ptr = ARRPTR(b);
71
if (GETBIT(GETSIGN(a), HASHVAL(*ptr)))
80
_intbig_contains(GISTTYPE * a, ArrayType *b)
82
int num = ARRNELEMS(b);
83
int4 *ptr = ARRPTR(b);
87
if (!GETBIT(GETSIGN(a), HASHVAL(*ptr)))
96
g_intbig_same(PG_FUNCTION_ARGS)
98
GISTTYPE *a = (GISTTYPE *) PG_GETARG_POINTER(0);
99
GISTTYPE *b = (GISTTYPE *) PG_GETARG_POINTER(1);
100
bool *result = (bool *) PG_GETARG_POINTER(2);
102
if (ISALLTRUE(a) && ISALLTRUE(b))
104
else if (ISALLTRUE(a))
106
else if (ISALLTRUE(b))
111
BITVECP sa = GETSIGN(a),
123
PG_RETURN_POINTER(result);
127
g_intbig_compress(PG_FUNCTION_ARGS)
129
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
134
ArrayType *in = (ArrayType *) PG_DETOAST_DATUM(entry->key);
137
GISTTYPE *res = (GISTTYPE *) palloc(CALCGTSIZE(0));
143
memset(res, 0, CALCGTSIZE(0));
144
res->len = CALCGTSIZE(0);
148
HASH(GETSIGN(res), *ptr);
152
retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
153
gistentryinit(*retval, PointerGetDatum(res),
154
entry->rel, entry->page,
155
entry->offset, res->len, FALSE);
157
if (in != (ArrayType *) PG_DETOAST_DATUM(entry->key))
160
PG_RETURN_POINTER(retval);
162
else if (!ISALLTRUE(DatumGetPointer(entry->key)))
166
BITVECP sign = GETSIGN(DatumGetPointer(entry->key));
170
if ((sign[i] & 0xff) != 0xff)
171
PG_RETURN_POINTER(entry);
174
res = (GISTTYPE *) palloc(CALCGTSIZE(ALLISTRUE));
175
res->len = CALCGTSIZE(ALLISTRUE);
176
res->flag = ALLISTRUE;
178
retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
179
gistentryinit(*retval, PointerGetDatum(res),
180
entry->rel, entry->page,
181
entry->offset, res->len, FALSE);
183
PG_RETURN_POINTER(retval);
186
PG_RETURN_POINTER(entry);
191
sizebitvec(BITVECP sign)
197
size += SUMBIT(sign);
198
sign = (BITVECP) (((char *) sign) + 1);
204
hemdistsign(BITVECP a, BITVECP b)
210
if (GETBIT(a, i) != GETBIT(b, i))
217
hemdist(GISTTYPE * a, GISTTYPE * b)
224
return SIGLENBIT - sizebitvec(GETSIGN(b));
226
else if (ISALLTRUE(b))
227
return SIGLENBIT - sizebitvec(GETSIGN(a));
229
return hemdistsign(GETSIGN(a), GETSIGN(b));
233
g_intbig_decompress(PG_FUNCTION_ARGS)
235
PG_RETURN_DATUM(PG_GETARG_DATUM(0));
239
unionkey(BITVECP sbase, GISTTYPE * add)
242
BITVECP sadd = GETSIGN(add);
253
g_intbig_union(PG_FUNCTION_ARGS)
255
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
256
int *size = (int *) PG_GETARG_POINTER(1);
263
MemSet((void *) base, 0, sizeof(BITVEC));
264
for (i = 0; i < entryvec->n; i++)
266
if (unionkey(base, GETENTRY(entryvec, i)))
273
len = CALCGTSIZE(flag);
274
result = (GISTTYPE *) palloc(len);
275
*size = result->len = len;
277
if (!ISALLTRUE(result))
278
memcpy((void *) GETSIGN(result), (void *) base, sizeof(BITVEC));
280
PG_RETURN_POINTER(result);
284
g_intbig_penalty(PG_FUNCTION_ARGS)
286
GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
287
GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
288
float *penalty = (float *) PG_GETARG_POINTER(2);
289
GISTTYPE *origval = (GISTTYPE *) DatumGetPointer(origentry->key);
290
GISTTYPE *newval = (GISTTYPE *) DatumGetPointer(newentry->key);
292
*penalty = hemdist(origval, newval);
293
PG_RETURN_POINTER(penalty);
304
comparecost(const void *a, const void *b)
306
return ((SPLITCOST *) a)->cost - ((SPLITCOST *) b)->cost;
311
g_intbig_picksplit(PG_FUNCTION_ARGS)
313
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
314
GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
326
OffsetNumber seed_1 = 0,
333
SPLITCOST *costvector;
337
maxoff = entryvec->n - 2;
338
nbytes = (maxoff + 2) * sizeof(OffsetNumber);
339
v->spl_left = (OffsetNumber *) palloc(nbytes);
340
v->spl_right = (OffsetNumber *) palloc(nbytes);
342
for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
344
_k = GETENTRY(entryvec, k);
345
for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
347
size_waste = hemdist(_k, GETENTRY(entryvec, j));
348
if (size_waste > waste)
359
right = v->spl_right;
362
if (seed_1 == 0 || seed_2 == 0)
368
/* form initial .. */
369
if (ISALLTRUE(GETENTRY(entryvec, seed_1)))
371
datum_l = (GISTTYPE *) palloc(GTHDRSIZE);
372
datum_l->len = GTHDRSIZE;
373
datum_l->flag = ALLISTRUE;
377
datum_l = (GISTTYPE *) palloc(GTHDRSIZE + SIGLEN);
378
datum_l->len = GTHDRSIZE + SIGLEN;
380
memcpy((void *) GETSIGN(datum_l), (void *) GETSIGN(GETENTRY(entryvec, seed_1)), sizeof(BITVEC));
382
if (ISALLTRUE(GETENTRY(entryvec, seed_2)))
384
datum_r = (GISTTYPE *) palloc(GTHDRSIZE);
385
datum_r->len = GTHDRSIZE;
386
datum_r->flag = ALLISTRUE;
390
datum_r = (GISTTYPE *) palloc(GTHDRSIZE + SIGLEN);
391
datum_r->len = GTHDRSIZE + SIGLEN;
393
memcpy((void *) GETSIGN(datum_r), (void *) GETSIGN(GETENTRY(entryvec, seed_2)), sizeof(BITVEC));
396
maxoff = OffsetNumberNext(maxoff);
397
/* sort before ... */
398
costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
399
for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
401
costvector[j - 1].pos = j;
402
_j = GETENTRY(entryvec, j);
403
size_alpha = hemdist(datum_l, _j);
404
size_beta = hemdist(datum_r, _j);
405
costvector[j - 1].cost = Abs(size_alpha - size_beta);
407
qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
409
union_l = GETSIGN(datum_l);
410
union_r = GETSIGN(datum_r);
412
for (k = 0; k < maxoff; k++)
414
j = costvector[k].pos;
421
else if (j == seed_2)
427
_j = GETENTRY(entryvec, j);
428
size_alpha = hemdist(datum_l, _j);
429
size_beta = hemdist(datum_r, _j);
431
if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.00001))
433
if (ISALLTRUE(datum_l) || ISALLTRUE(_j))
435
if (!ISALLTRUE(datum_l))
436
MemSet((void *) union_l, 0xff, sizeof(BITVEC));
442
union_l[i] |= ptr[i];
450
if (ISALLTRUE(datum_r) || ISALLTRUE(_j))
452
if (!ISALLTRUE(datum_r))
453
MemSet((void *) union_r, 0xff, sizeof(BITVEC));
459
union_r[i] |= ptr[i];
467
*right = *left = FirstOffsetNumber;
470
v->spl_ldatum = PointerGetDatum(datum_l);
471
v->spl_rdatum = PointerGetDatum(datum_r);
473
PG_RETURN_POINTER(v);
477
g_intbig_consistent(PG_FUNCTION_ARGS)
479
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
480
ArrayType *query = (ArrayType *) PG_GETARG_POINTER(1);
481
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
484
if (ISALLTRUE(DatumGetPointer(entry->key)))
485
PG_RETURN_BOOL(true);
487
if (strategy == BooleanSearchStrategy)
489
PG_RETURN_BOOL(signconsistent((QUERYTYPE *) query,
490
GETSIGN(DatumGetPointer(entry->key)),
494
/* XXX what about toasted input? */
495
if (ARRISVOID(query))
500
case RTOverlapStrategyNumber:
501
retval = _intbig_overlap((GISTTYPE *) DatumGetPointer(entry->key), query);
503
case RTSameStrategyNumber:
504
if (GIST_LEAF(entry))
507
num = ARRNELEMS(query);
508
int4 *ptr = ARRPTR(query);
513
memset(qp, 0, sizeof(BITVEC));
521
de = GETSIGN((GISTTYPE *) DatumGetPointer(entry->key));
534
retval = _intbig_contains((GISTTYPE *) DatumGetPointer(entry->key), query);
536
case RTContainsStrategyNumber:
537
retval = _intbig_contains((GISTTYPE *) DatumGetPointer(entry->key), query);
539
case RTContainedByStrategyNumber:
540
if (GIST_LEAF(entry))
543
num = ARRNELEMS(query);
544
int4 *ptr = ARRPTR(query);
549
memset(qp, 0, sizeof(BITVEC));
557
de = GETSIGN((GISTTYPE *) DatumGetPointer(entry->key));
570
retval = _intbig_overlap((GISTTYPE *) DatumGetPointer(entry->key), query);
575
PG_RETURN_BOOL(retval);