Age Owner Branch data TLA Line data Source code
1 : : /*
2 : : * contrib/intarray/_intbig_gist.c
3 : : */
4 : : #include "postgres.h"
5 : :
6 : : #include <math.h>
7 : :
8 : : #include "_int.h"
9 : : #include "access/gist.h"
10 : : #include "access/reloptions.h"
11 : : #include "access/stratnum.h"
12 : : #include "common/int.h"
13 : : #include "port/pg_bitutils.h"
14 : :
15 : : #define GETENTRY(vec,pos) ((GISTTYPE *) DatumGetPointer((vec)->vector[(pos)].key))
16 : : /*
17 : : ** _intbig methods
18 : : */
7613 bruce@momjian.us 19 :CBC 2 : PG_FUNCTION_INFO_V1(g_intbig_consistent);
20 : 2 : PG_FUNCTION_INFO_V1(g_intbig_compress);
21 : 2 : PG_FUNCTION_INFO_V1(g_intbig_decompress);
22 : 2 : PG_FUNCTION_INFO_V1(g_intbig_penalty);
23 : 2 : PG_FUNCTION_INFO_V1(g_intbig_picksplit);
24 : 2 : PG_FUNCTION_INFO_V1(g_intbig_union);
25 : 2 : PG_FUNCTION_INFO_V1(g_intbig_same);
1476 akorotkov@postgresql 26 : 2 : PG_FUNCTION_INFO_V1(g_intbig_options);
27 : :
7613 bruce@momjian.us 28 : 1 : PG_FUNCTION_INFO_V1(_intbig_in);
29 : 1 : PG_FUNCTION_INFO_V1(_intbig_out);
30 : :
31 : : Datum
7168 bruce@momjian.us 32 :UBC 0 : _intbig_in(PG_FUNCTION_ARGS)
33 : : {
34 [ # # ]: 0 : ereport(ERROR,
35 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
36 : : errmsg("cannot accept a value of type %s", "intbig_gkey")));
37 : :
38 : : PG_RETURN_VOID(); /* keep compiler quiet */
39 : : }
40 : :
41 : : Datum
42 : 0 : _intbig_out(PG_FUNCTION_ARGS)
43 : : {
44 [ # # ]: 0 : ereport(ERROR,
45 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
46 : : errmsg("cannot display a value of type %s", "intbig_gkey")));
47 : :
48 : : PG_RETURN_VOID(); /* keep compiler quiet */
49 : : }
50 : :
51 : : static GISTTYPE *
1476 akorotkov@postgresql 52 :CBC 87223 : _intbig_alloc(bool allistrue, int siglen, BITVECP sign)
53 : : {
54 [ - + ]: 87223 : int flag = allistrue ? ALLISTRUE : 0;
55 [ + - ]: 87223 : int size = CALCGTSIZE(flag, siglen);
56 : 87223 : GISTTYPE *res = (GISTTYPE *) palloc(size);
57 : :
58 : 87223 : SET_VARSIZE(res, size);
59 : 87223 : res->flag = flag;
60 : :
61 [ + - ]: 87223 : if (!allistrue)
62 : : {
63 [ + + ]: 87223 : if (sign)
64 : 9094 : memcpy(GETSIGN(res), sign, siglen);
65 : : else
66 : 78129 : memset(GETSIGN(res), 0, siglen);
67 : : }
68 : :
69 : 87223 : return res;
70 : : }
71 : :
72 : :
73 : : /*********************************************************************
74 : : ** intbig functions
75 : : *********************************************************************/
76 : : static bool
77 : 7474 : _intbig_overlap(GISTTYPE *a, ArrayType *b, int siglen)
78 : : {
7168 bruce@momjian.us 79 : 7474 : int num = ARRNELEMS(b);
4311 peter_e@gmx.net 80 [ - + ]: 7474 : int32 *ptr = ARRPTR(b);
81 : :
6721 tgl@sss.pgh.pa.us 82 [ - + - - : 7474 : CHECKARRVALID(b);
- - ]
83 : :
7168 bruce@momjian.us 84 [ + + ]: 19178 : while (num--)
85 : : {
1476 akorotkov@postgresql 86 [ + + ]: 13749 : if (GETBIT(GETSIGN(a), HASHVAL(*ptr, siglen)))
7613 bruce@momjian.us 87 : 2045 : return true;
88 : 11704 : ptr++;
89 : : }
90 : :
91 : 5429 : return false;
92 : : }
93 : :
94 : : static bool
1476 akorotkov@postgresql 95 : 9243 : _intbig_contains(GISTTYPE *a, ArrayType *b, int siglen)
96 : : {
7168 bruce@momjian.us 97 : 9243 : int num = ARRNELEMS(b);
4311 peter_e@gmx.net 98 [ - + ]: 9243 : int32 *ptr = ARRPTR(b);
99 : :
6721 tgl@sss.pgh.pa.us 100 [ - + - - : 9243 : CHECKARRVALID(b);
- - ]
101 : :
7168 bruce@momjian.us 102 [ + + ]: 13840 : while (num--)
103 : : {
1476 akorotkov@postgresql 104 [ + + ]: 12329 : if (!GETBIT(GETSIGN(a), HASHVAL(*ptr, siglen)))
7613 bruce@momjian.us 105 : 7732 : return false;
106 : 4597 : ptr++;
107 : : }
108 : :
109 : 1511 : return true;
110 : : }
111 : :
112 : : Datum
7168 113 : 62761 : g_intbig_same(PG_FUNCTION_ARGS)
114 : : {
7613 115 : 62761 : GISTTYPE *a = (GISTTYPE *) PG_GETARG_POINTER(0);
116 : 62761 : GISTTYPE *b = (GISTTYPE *) PG_GETARG_POINTER(1);
7168 117 : 62761 : bool *result = (bool *) PG_GETARG_POINTER(2);
1476 akorotkov@postgresql 118 [ + - ]: 62761 : int siglen = GET_SIGLEN();
119 : :
7613 bruce@momjian.us 120 [ - + - - ]: 62761 : if (ISALLTRUE(a) && ISALLTRUE(b))
7613 bruce@momjian.us 121 :UBC 0 : *result = true;
7613 bruce@momjian.us 122 [ - + ]:CBC 62761 : else if (ISALLTRUE(a))
7613 bruce@momjian.us 123 :UBC 0 : *result = false;
7613 bruce@momjian.us 124 [ - + ]:CBC 62761 : else if (ISALLTRUE(b))
7613 bruce@momjian.us 125 :UBC 0 : *result = false;
126 : : else
127 : : {
128 : : int32 i;
7168 bruce@momjian.us 129 :CBC 62761 : BITVECP sa = GETSIGN(a),
130 : 62761 : sb = GETSIGN(b);
131 : :
7613 132 : 62761 : *result = true;
1476 akorotkov@postgresql 133 [ + + ]: 46558776 : LOOPBYTE(siglen)
134 : : {
5994 bruce@momjian.us 135 [ + + ]: 46530310 : if (sa[i] != sb[i])
136 : : {
137 : 34295 : *result = false;
138 : 34295 : break;
139 : : }
140 : : }
141 : : }
7613 142 : 62761 : PG_RETURN_POINTER(result);
143 : : }
144 : :
145 : : Datum
146 : 56908 : g_intbig_compress(PG_FUNCTION_ARGS)
147 : : {
148 : 56908 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
1476 akorotkov@postgresql 149 [ + - ]: 56908 : int siglen = GET_SIGLEN();
150 : :
7168 bruce@momjian.us 151 [ + + ]: 56908 : if (entry->leafkey)
152 : : {
153 : : GISTENTRY *retval;
4844 tgl@sss.pgh.pa.us 154 : 13514 : ArrayType *in = DatumGetArrayTypeP(entry->key);
155 : : int32 *ptr;
156 : : int num;
1476 akorotkov@postgresql 157 : 13514 : GISTTYPE *res = _intbig_alloc(false, siglen, NULL);
158 : :
6721 tgl@sss.pgh.pa.us 159 [ - + - - : 13514 : CHECKARRVALID(in);
- - ]
4844 160 [ + + ]: 13514 : if (ARRISEMPTY(in))
161 : : {
6721 162 : 18 : ptr = NULL;
163 : 18 : num = 0;
164 : : }
165 : : else
166 : : {
167 [ - + ]: 13496 : ptr = ARRPTR(in);
168 : 13496 : num = ARRNELEMS(in);
169 : : }
170 : :
7168 bruce@momjian.us 171 [ + + ]: 67822 : while (num--)
172 : : {
1476 akorotkov@postgresql 173 : 54308 : HASH(GETSIGN(res), *ptr, siglen);
7613 bruce@momjian.us 174 : 54308 : ptr++;
175 : : }
176 : :
177 : 13514 : retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
178 : 13514 : gistentryinit(*retval, PointerGetDatum(res),
179 : : entry->rel, entry->page,
180 : : entry->offset, false);
181 : :
182 : 13514 : PG_RETURN_POINTER(retval);
183 : : }
7168 184 [ + - ]: 43394 : else if (!ISALLTRUE(DatumGetPointer(entry->key)))
185 : : {
186 : : GISTENTRY *retval;
187 : : int i;
188 : 43394 : BITVECP sign = GETSIGN(DatumGetPointer(entry->key));
189 : : GISTTYPE *res;
190 : :
1476 akorotkov@postgresql 191 [ + - ]: 55046 : LOOPBYTE(siglen)
192 : : {
5994 bruce@momjian.us 193 [ + + ]: 55046 : if ((sign[i] & 0xff) != 0xff)
194 : 43394 : PG_RETURN_POINTER(entry);
195 : : }
196 : :
1476 akorotkov@postgresql 197 :UBC 0 : res = _intbig_alloc(true, siglen, sign);
7613 bruce@momjian.us 198 : 0 : retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
199 : 0 : gistentryinit(*retval, PointerGetDatum(res),
200 : : entry->rel, entry->page,
201 : : entry->offset, false);
202 : :
203 : 0 : PG_RETURN_POINTER(retval);
204 : : }
205 : :
206 : 0 : PG_RETURN_POINTER(entry);
207 : : }
208 : :
209 : :
210 : : static int32
1476 akorotkov@postgresql 211 : 0 : sizebitvec(BITVECP sign, int siglen)
212 : : {
213 : 0 : return pg_popcount(sign, siglen);
214 : : }
215 : :
216 : : static int
1476 akorotkov@postgresql 217 :CBC 498497 : hemdistsign(BITVECP a, BITVECP b, int siglen)
218 : : {
219 : : int i,
220 : : diff,
7168 bruce@momjian.us 221 : 498497 : dist = 0;
222 : :
1476 akorotkov@postgresql 223 [ + + ]: 454744229 : LOOPBYTE(siglen)
224 : : {
5994 bruce@momjian.us 225 : 454245732 : diff = (unsigned char) (a[i] ^ b[i]);
226 : : /* Using the popcount functions here isn't likely to win */
1885 tgl@sss.pgh.pa.us 227 : 454245732 : dist += pg_number_of_ones[diff];
228 : : }
7168 bruce@momjian.us 229 : 498497 : return dist;
230 : : }
231 : :
232 : : static int
1476 akorotkov@postgresql 233 : 498497 : hemdist(GISTTYPE *a, GISTTYPE *b, int siglen)
234 : : {
7168 bruce@momjian.us 235 [ - + ]: 498497 : if (ISALLTRUE(a))
236 : : {
7168 bruce@momjian.us 237 [ # # ]:UBC 0 : if (ISALLTRUE(b))
238 : 0 : return 0;
239 : : else
1476 akorotkov@postgresql 240 : 0 : return SIGLENBIT(siglen) - sizebitvec(GETSIGN(b), siglen);
241 : : }
7168 bruce@momjian.us 242 [ - + ]:CBC 498497 : else if (ISALLTRUE(b))
1476 akorotkov@postgresql 243 :UBC 0 : return SIGLENBIT(siglen) - sizebitvec(GETSIGN(a), siglen);
244 : :
1476 akorotkov@postgresql 245 :CBC 498497 : return hemdistsign(GETSIGN(a), GETSIGN(b), siglen);
246 : : }
247 : :
248 : : Datum
7613 bruce@momjian.us 249 : 590834 : g_intbig_decompress(PG_FUNCTION_ARGS)
250 : : {
251 : 590834 : PG_RETURN_DATUM(PG_GETARG_DATUM(0));
252 : : }
253 : :
254 : : static int32
1476 akorotkov@postgresql 255 : 129595 : unionkey(BITVECP sbase, GISTTYPE *add, int siglen)
256 : : {
257 : : int32 i;
7168 bruce@momjian.us 258 : 129595 : BITVECP sadd = GETSIGN(add);
259 : :
7613 260 [ - + ]: 129595 : if (ISALLTRUE(add))
7613 bruce@momjian.us 261 :UBC 0 : return 1;
1476 akorotkov@postgresql 262 [ + + ]:CBC 216458879 : LOOPBYTE(siglen)
5994 bruce@momjian.us 263 : 216329284 : sbase[i] |= sadd[i];
7613 264 : 129595 : return 0;
265 : : }
266 : :
267 : : Datum
7168 268 : 64615 : g_intbig_union(PG_FUNCTION_ARGS)
269 : : {
270 : 64615 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
271 : 64615 : int *size = (int *) PG_GETARG_POINTER(1);
1476 akorotkov@postgresql 272 [ + - ]: 64615 : int siglen = GET_SIGLEN();
273 : : int32 i;
274 : 64615 : GISTTYPE *result = _intbig_alloc(false, siglen, NULL);
275 : 64615 : BITVECP base = GETSIGN(result);
276 : :
7168 bruce@momjian.us 277 [ + + ]: 194210 : for (i = 0; i < entryvec->n; i++)
278 : : {
1476 akorotkov@postgresql 279 [ - + ]: 129595 : if (unionkey(base, GETENTRY(entryvec, i), siglen))
280 : : {
1476 akorotkov@postgresql 281 :UBC 0 : result->flag |= ALLISTRUE;
282 : 0 : SET_VARSIZE(result, CALCGTSIZE(ALLISTRUE, siglen));
7613 bruce@momjian.us 283 : 0 : break;
284 : : }
285 : : }
286 : :
1476 akorotkov@postgresql 287 :CBC 64615 : *size = VARSIZE(result);
288 : :
7613 bruce@momjian.us 289 : 64615 : PG_RETURN_POINTER(result);
290 : : }
291 : :
292 : : Datum
7168 293 : 299792 : g_intbig_penalty(PG_FUNCTION_ARGS)
294 : : {
7613 295 : 299792 : GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
296 : 299792 : GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
7168 297 : 299792 : float *penalty = (float *) PG_GETARG_POINTER(2);
7613 298 : 299792 : GISTTYPE *origval = (GISTTYPE *) DatumGetPointer(origentry->key);
299 : 299792 : GISTTYPE *newval = (GISTTYPE *) DatumGetPointer(newentry->key);
1476 akorotkov@postgresql 300 [ + - ]: 299792 : int siglen = GET_SIGLEN();
301 : :
302 : 299792 : *penalty = hemdist(origval, newval, siglen);
7613 bruce@momjian.us 303 : 299792 : PG_RETURN_POINTER(penalty);
304 : : }
305 : :
306 : :
307 : : typedef struct
308 : : {
309 : : OffsetNumber pos;
310 : : int32 cost;
311 : : } SPLITCOST;
312 : :
313 : : static int
7168 314 : 39871 : comparecost(const void *a, const void *b)
315 : : {
58 nathan@postgresql.or 316 :GNC 79742 : return pg_cmp_s32(((const SPLITCOST *) a)->cost,
317 : 39871 : ((const SPLITCOST *) b)->cost);
318 : : }
319 : :
320 : :
321 : : Datum
7168 bruce@momjian.us 322 :CBC 4547 : g_intbig_picksplit(PG_FUNCTION_ARGS)
323 : : {
324 : 4547 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
325 : 4547 : GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
1476 akorotkov@postgresql 326 [ + - ]: 4547 : int siglen = GET_SIGLEN();
327 : : OffsetNumber k,
328 : : j;
329 : : GISTTYPE *datum_l,
330 : : *datum_r;
331 : : BITVECP union_l,
332 : : union_r;
333 : : int32 size_alpha,
334 : : size_beta;
335 : : int32 size_waste,
7168 bruce@momjian.us 336 : 4547 : waste = -1;
337 : : int32 nbytes;
338 : 4547 : OffsetNumber seed_1 = 0,
339 : 4547 : seed_2 = 0;
340 : : OffsetNumber *left,
341 : : *right;
342 : : OffsetNumber maxoff;
343 : : BITVECP ptr;
344 : : int i;
345 : : SPLITCOST *costvector;
346 : : GISTTYPE *_k,
347 : : *_j;
348 : :
349 : 4547 : maxoff = entryvec->n - 2;
350 : 4547 : nbytes = (maxoff + 2) * sizeof(OffsetNumber);
351 : 4547 : v->spl_left = (OffsetNumber *) palloc(nbytes);
352 : 4547 : v->spl_right = (OffsetNumber *) palloc(nbytes);
353 : :
354 [ + + ]: 20889 : for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
355 : : {
356 : 16342 : _k = GETENTRY(entryvec, k);
357 [ + + ]: 131491 : for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
358 : : {
1476 akorotkov@postgresql 359 : 115149 : size_waste = hemdist(_k, GETENTRY(entryvec, j), siglen);
7168 bruce@momjian.us 360 [ + + ]: 115149 : if (size_waste > waste)
361 : : {
362 : 8907 : waste = size_waste;
363 : 8907 : seed_1 = k;
364 : 8907 : seed_2 = j;
365 : : }
366 : : }
367 : : }
368 : :
369 : 4547 : left = v->spl_left;
370 : 4547 : v->spl_nleft = 0;
371 : 4547 : right = v->spl_right;
372 : 4547 : v->spl_nright = 0;
373 : :
374 [ + - - + ]: 4547 : if (seed_1 == 0 || seed_2 == 0)
375 : : {
7168 bruce@momjian.us 376 :UBC 0 : seed_1 = 1;
377 : 0 : seed_2 = 2;
378 : : }
379 : :
380 : : /* form initial .. */
1476 akorotkov@postgresql 381 :CBC 4547 : datum_l = _intbig_alloc(ISALLTRUE(GETENTRY(entryvec, seed_1)), siglen,
382 : 4547 : GETSIGN(GETENTRY(entryvec, seed_1)));
383 : 4547 : datum_r = _intbig_alloc(ISALLTRUE(GETENTRY(entryvec, seed_2)), siglen,
384 : 4547 : GETSIGN(GETENTRY(entryvec, seed_2)));
385 : :
7168 bruce@momjian.us 386 : 4547 : maxoff = OffsetNumberNext(maxoff);
387 : : /* sort before ... */
388 : 4547 : costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
389 [ + + ]: 29983 : for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
390 : : {
391 : 25436 : costvector[j - 1].pos = j;
392 : 25436 : _j = GETENTRY(entryvec, j);
1476 akorotkov@postgresql 393 : 25436 : size_alpha = hemdist(datum_l, _j, siglen);
394 : 25436 : size_beta = hemdist(datum_r, _j, siglen);
555 peter@eisentraut.org 395 : 25436 : costvector[j - 1].cost = abs(size_alpha - size_beta);
396 : : }
432 397 : 4547 : qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
398 : :
7168 bruce@momjian.us 399 : 4547 : union_l = GETSIGN(datum_l);
400 : 4547 : union_r = GETSIGN(datum_r);
401 : :
402 [ + + ]: 29983 : for (k = 0; k < maxoff; k++)
403 : : {
404 : 25436 : j = costvector[k].pos;
405 [ + + ]: 25436 : if (j == seed_1)
406 : : {
407 : 4547 : *left++ = j;
408 : 4547 : v->spl_nleft++;
409 : 4547 : continue;
410 : : }
411 [ + + ]: 20889 : else if (j == seed_2)
412 : : {
413 : 4547 : *right++ = j;
414 : 4547 : v->spl_nright++;
415 : 4547 : continue;
416 : : }
417 : 16342 : _j = GETENTRY(entryvec, j);
1476 akorotkov@postgresql 418 : 16342 : size_alpha = hemdist(datum_l, _j, siglen);
419 : 16342 : size_beta = hemdist(datum_r, _j, siglen);
420 : :
7168 bruce@momjian.us 421 [ + + ]: 16342 : if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.00001))
422 : : {
423 [ + - - + ]: 8122 : if (ISALLTRUE(datum_l) || ISALLTRUE(_j))
424 : : {
7168 bruce@momjian.us 425 [ # # ]:UBC 0 : if (!ISALLTRUE(datum_l))
432 peter@eisentraut.org 426 : 0 : memset(union_l, 0xff, siglen);
427 : : }
428 : : else
429 : : {
7168 bruce@momjian.us 430 :CBC 8122 : ptr = GETSIGN(_j);
1476 akorotkov@postgresql 431 [ + + ]: 9357278 : LOOPBYTE(siglen)
5994 bruce@momjian.us 432 : 9349156 : union_l[i] |= ptr[i];
433 : : }
7168 434 : 8122 : *left++ = j;
435 : 8122 : v->spl_nleft++;
436 : : }
437 : : else
438 : : {
439 [ + - - + ]: 8220 : if (ISALLTRUE(datum_r) || ISALLTRUE(_j))
440 : : {
7168 bruce@momjian.us 441 [ # # ]:UBC 0 : if (!ISALLTRUE(datum_r))
432 peter@eisentraut.org 442 : 0 : memset(union_r, 0xff, siglen);
443 : : }
444 : : else
445 : : {
7168 bruce@momjian.us 446 :CBC 8220 : ptr = GETSIGN(_j);
1476 akorotkov@postgresql 447 [ + + ]: 9775456 : LOOPBYTE(siglen)
5994 bruce@momjian.us 448 : 9767236 : union_r[i] |= ptr[i];
449 : : }
7168 450 : 8220 : *right++ = j;
451 : 8220 : v->spl_nright++;
452 : : }
453 : : }
454 : :
455 : 4547 : *right = *left = FirstOffsetNumber;
456 : 4547 : pfree(costvector);
457 : :
458 : 4547 : v->spl_ldatum = PointerGetDatum(datum_l);
459 : 4547 : v->spl_rdatum = PointerGetDatum(datum_r);
460 : :
461 : 4547 : PG_RETURN_POINTER(v);
462 : : }
463 : :
464 : : Datum
7613 465 : 68493 : g_intbig_consistent(PG_FUNCTION_ARGS)
466 : : {
467 : 68493 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
4844 tgl@sss.pgh.pa.us 468 : 68493 : ArrayType *query = PG_GETARG_ARRAYTYPE_P(1);
7613 bruce@momjian.us 469 : 68493 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
470 : :
471 : : /* Oid subtype = PG_GETARG_OID(3); */
5844 tgl@sss.pgh.pa.us 472 : 68493 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
1476 akorotkov@postgresql 473 [ + - ]: 68493 : int siglen = GET_SIGLEN();
474 : : bool retval;
475 : :
476 : : /* All cases served by this function are inexact */
5844 tgl@sss.pgh.pa.us 477 : 68493 : *recheck = true;
478 : :
7168 bruce@momjian.us 479 [ - + ]: 68493 : if (ISALLTRUE(DatumGetPointer(entry->key)))
7613 bruce@momjian.us 480 :UBC 0 : PG_RETURN_BOOL(true);
481 : :
7168 bruce@momjian.us 482 [ + + ]:CBC 68493 : if (strategy == BooleanSearchStrategy)
483 : : {
6402 484 : 51267 : retval = signconsistent((QUERYTYPE *) query,
485 : 51267 : GETSIGN(DatumGetPointer(entry->key)),
486 : : siglen,
487 : : false);
488 [ - + ]: 51267 : PG_FREE_IF_COPY(query, 1);
6586 teodor@sigaev.ru 489 : 51267 : PG_RETURN_BOOL(retval);
490 : : }
491 : :
6721 tgl@sss.pgh.pa.us 492 [ - + - - : 17226 : CHECKARRVALID(query);
- - ]
493 : :
7613 bruce@momjian.us 494 [ + + + - : 17226 : switch (strategy)
- ]
495 : : {
496 : 7474 : case RTOverlapStrategyNumber:
1476 akorotkov@postgresql 497 : 7474 : retval = _intbig_overlap((GISTTYPE *) DatumGetPointer(entry->key),
498 : : query, siglen);
7613 bruce@momjian.us 499 : 7474 : break;
500 : 1220 : case RTSameStrategyNumber:
7168 501 [ + + ]: 1220 : if (GIST_LEAF(entry))
502 : : {
503 : : int i,
504 : 509 : num = ARRNELEMS(query);
4311 peter_e@gmx.net 505 [ - + ]: 509 : int32 *ptr = ARRPTR(query);
1476 akorotkov@postgresql 506 : 509 : BITVECP dq = palloc0(siglen),
507 : : de;
508 : :
7168 bruce@momjian.us 509 [ + + ]: 2036 : while (num--)
510 : : {
1476 akorotkov@postgresql 511 : 1527 : HASH(dq, *ptr, siglen);
7613 bruce@momjian.us 512 : 1527 : ptr++;
513 : : }
514 : :
7168 515 : 509 : de = GETSIGN((GISTTYPE *) DatumGetPointer(entry->key));
516 : 509 : retval = true;
1476 akorotkov@postgresql 517 [ + + ]: 3503 : LOOPBYTE(siglen)
518 : : {
5994 bruce@momjian.us 519 [ + + ]: 3501 : if (de[i] != dq[i])
520 : : {
521 : 507 : retval = false;
522 : 507 : break;
523 : : }
524 : : }
525 : :
1476 akorotkov@postgresql 526 : 509 : pfree(dq);
527 : : }
528 : : else
529 : 711 : retval = _intbig_contains((GISTTYPE *) DatumGetPointer(entry->key),
530 : : query, siglen);
7613 bruce@momjian.us 531 : 1220 : break;
532 : 8532 : case RTContainsStrategyNumber:
533 : : case RTOldContainsStrategyNumber:
1476 akorotkov@postgresql 534 : 8532 : retval = _intbig_contains((GISTTYPE *) DatumGetPointer(entry->key),
535 : : query, siglen);
7613 bruce@momjian.us 536 : 8532 : break;
7613 bruce@momjian.us 537 :UBC 0 : case RTContainedByStrategyNumber:
538 : : case RTOldContainedByStrategyNumber:
539 : :
540 : : /*
541 : : * This code is unreachable as of intarray 1.4, because the <@
542 : : * operator has been removed from the opclass. We keep it for now
543 : : * to support older versions of the SQL definitions.
544 : : */
7168 545 [ # # ]: 0 : if (GIST_LEAF(entry))
546 : : {
547 : : int i,
548 : 0 : num = ARRNELEMS(query);
4311 peter_e@gmx.net 549 [ # # ]: 0 : int32 *ptr = ARRPTR(query);
1476 akorotkov@postgresql 550 : 0 : BITVECP dq = palloc0(siglen),
551 : : de;
552 : :
7168 bruce@momjian.us 553 [ # # ]: 0 : while (num--)
554 : : {
1476 akorotkov@postgresql 555 : 0 : HASH(dq, *ptr, siglen);
7613 bruce@momjian.us 556 : 0 : ptr++;
557 : : }
558 : :
7168 559 : 0 : de = GETSIGN((GISTTYPE *) DatumGetPointer(entry->key));
560 : 0 : retval = true;
1476 akorotkov@postgresql 561 [ # # ]: 0 : LOOPBYTE(siglen)
562 : : {
5994 bruce@momjian.us 563 [ # # ]: 0 : if (de[i] & ~dq[i])
564 : : {
565 : 0 : retval = false;
566 : 0 : break;
567 : : }
568 : : }
569 : : }
570 : : else
571 : : {
572 : : /*
573 : : * Unfortunately, because empty arrays could be anywhere in
574 : : * the index, we must search the whole tree.
575 : : */
1713 tgl@sss.pgh.pa.us 576 : 0 : retval = true;
577 : : }
7613 bruce@momjian.us 578 : 0 : break;
579 : 0 : default:
2433 peter_e@gmx.net 580 : 0 : retval = false;
581 : : }
6402 bruce@momjian.us 582 [ - + ]:CBC 17226 : PG_FREE_IF_COPY(query, 1);
7613 583 : 17226 : PG_RETURN_BOOL(retval);
584 : : }
585 : :
586 : : Datum
1476 akorotkov@postgresql 587 : 10 : g_intbig_options(PG_FUNCTION_ARGS)
588 : : {
589 : 10 : local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0);
590 : :
591 : 10 : init_local_reloptions(relopts, sizeof(GISTIntArrayBigOptions));
592 : 10 : add_local_int_reloption(relopts, "siglen",
593 : : "signature length in bytes",
594 : : SIGLEN_DEFAULT, 1, SIGLEN_MAX,
595 : : offsetof(GISTIntArrayBigOptions, siglen));
596 : :
597 : 10 : PG_RETURN_VOID();
598 : : }
|