LCOV - differential code coverage report
Current view: top level - contrib/intarray - _intbig_gist.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 83.3 % 281 234 2 8 27 10 10 113 2 109 25 115 2 2
Current Date: 2023-04-08 15:15:32 Functions: 89.3 % 28 25 3 25 3 25
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

Generated by: LCOV version v1.16-55-g56c0a2a