LCOV - code coverage report
Current view: top level - contrib/intarray - _int_tool.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 96.2 % 182 175
Test Date: 2026-05-17 14:16:24 Functions: 93.8 % 16 15
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*
       2              :  * contrib/intarray/_int_tool.c
       3              :  */
       4              : #include "postgres.h"
       5              : 
       6              : #include <limits.h>
       7              : 
       8              : #include "_int.h"
       9              : #include "catalog/pg_type.h"
      10              : #include "common/int.h"
      11              : #include "lib/qunique.h"
      12              : 
      13              : /* arguments are assumed sorted & unique-ified */
      14              : bool
      15        96940 : inner_int_contains(ArrayType *a, ArrayType *b)
      16              : {
      17              :     int         na,
      18              :                 nb;
      19              :     int         i,
      20              :                 j,
      21              :                 n;
      22              :     int        *da,
      23              :                *db;
      24              : 
      25        96940 :     na = ARRNELEMS(a);
      26        96940 :     nb = ARRNELEMS(b);
      27        96940 :     da = ARRPTR(a);
      28        96940 :     db = ARRPTR(b);
      29              : 
      30        96940 :     i = j = n = 0;
      31       238259 :     while (i < na && j < nb)
      32              :     {
      33       231345 :         if (da[i] < db[j])
      34       134558 :             i++;
      35        96787 :         else if (da[i] == db[j])
      36              :         {
      37         6761 :             n++;
      38         6761 :             i++;
      39         6761 :             j++;
      40              :         }
      41              :         else
      42        90026 :             break;              /* db[j] is not in da */
      43              :     }
      44              : 
      45        96940 :     return (n == nb);
      46              : }
      47              : 
      48              : /* arguments are assumed sorted */
      49              : bool
      50        24455 : inner_int_overlap(ArrayType *a, ArrayType *b)
      51              : {
      52              :     int         na,
      53              :                 nb;
      54              :     int         i,
      55              :                 j;
      56              :     int        *da,
      57              :                *db;
      58              : 
      59        24455 :     na = ARRNELEMS(a);
      60        24455 :     nb = ARRNELEMS(b);
      61        24455 :     da = ARRPTR(a);
      62        24455 :     db = ARRPTR(b);
      63              : 
      64        24455 :     i = j = 0;
      65       114469 :     while (i < na && j < nb)
      66              :     {
      67        92924 :         if (da[i] < db[j])
      68        46865 :             i++;
      69        46059 :         else if (da[i] == db[j])
      70         2910 :             return true;
      71              :         else
      72        43149 :             j++;
      73              :     }
      74              : 
      75        21545 :     return false;
      76              : }
      77              : 
      78              : ArrayType *
      79      2203538 : inner_int_union(ArrayType *a, ArrayType *b)
      80              : {
      81      2203538 :     ArrayType  *r = NULL;
      82              : 
      83      2203538 :     CHECKARRVALID(a);
      84      2203538 :     CHECKARRVALID(b);
      85              : 
      86      2203538 :     if (ARRISEMPTY(a) && ARRISEMPTY(b))
      87          127 :         return new_intArrayType(0);
      88      2203411 :     if (ARRISEMPTY(a))
      89        13287 :         r = copy_intArrayType(b);
      90      2203411 :     if (ARRISEMPTY(b))
      91         4201 :         r = copy_intArrayType(a);
      92              : 
      93      2203411 :     if (!r)
      94              :     {
      95      2185923 :         int         na = ARRNELEMS(a),
      96      2185923 :                     nb = ARRNELEMS(b);
      97      2185923 :         int        *da = ARRPTR(a),
      98      2185923 :                    *db = ARRPTR(b);
      99              :         int         i,
     100              :                     j,
     101              :                    *dr;
     102              : 
     103      2185923 :         r = new_intArrayType(na + nb);
     104      2185923 :         dr = ARRPTR(r);
     105              : 
     106              :         /* union */
     107      2185923 :         i = j = 0;
     108     80017771 :         while (i < na && j < nb)
     109              :         {
     110     77831848 :             if (da[i] == db[j])
     111              :             {
     112      4827239 :                 *dr++ = da[i++];
     113      4827239 :                 j++;
     114              :             }
     115     73004609 :             else if (da[i] < db[j])
     116     61629257 :                 *dr++ = da[i++];
     117              :             else
     118     11375352 :                 *dr++ = db[j++];
     119              :         }
     120              : 
     121      7622453 :         while (i < na)
     122      5436530 :             *dr++ = da[i++];
     123      4097136 :         while (j < nb)
     124      1911213 :             *dr++ = db[j++];
     125              : 
     126      2185923 :         r = resize_intArrayType(r, dr - ARRPTR(r));
     127              :     }
     128              : 
     129      2203411 :     if (ARRNELEMS(r) > 1)
     130      2203402 :         r = _int_unique(r);
     131              : 
     132      2203411 :     return r;
     133              : }
     134              : 
     135              : ArrayType *
     136      1772432 : inner_int_inter(ArrayType *a, ArrayType *b)
     137              : {
     138              :     ArrayType  *r;
     139              :     int         na,
     140              :                 nb;
     141              :     int        *da,
     142              :                *db,
     143              :                *dr;
     144              :     int         i,
     145              :                 j,
     146              :                 k;
     147              : 
     148      1772432 :     if (ARRISEMPTY(a) || ARRISEMPTY(b))
     149        17039 :         return new_intArrayType(0);
     150              : 
     151      1755393 :     na = ARRNELEMS(a);
     152      1755393 :     nb = ARRNELEMS(b);
     153      1755393 :     da = ARRPTR(a);
     154      1755393 :     db = ARRPTR(b);
     155      1755393 :     r = new_intArrayType(Min(na, nb));
     156      1755393 :     dr = ARRPTR(r);
     157              : 
     158      1755393 :     i = j = k = 0;
     159     21398270 :     while (i < na && j < nb)
     160              :     {
     161     19642877 :         if (da[i] < db[j])
     162      9087681 :             i++;
     163     10555196 :         else if (da[i] == db[j])
     164              :         {
     165      1649956 :             if (k == 0 || dr[k - 1] != db[j])
     166      1649956 :                 dr[k++] = db[j];
     167      1649956 :             i++;
     168      1649956 :             j++;
     169              :         }
     170              :         else
     171      8905240 :             j++;
     172              :     }
     173              : 
     174      1755393 :     if (k == 0)
     175              :     {
     176      1393266 :         pfree(r);
     177      1393266 :         return new_intArrayType(0);
     178              :     }
     179              :     else
     180       362127 :         return resize_intArrayType(r, k);
     181              : }
     182              : 
     183              : void
     184      4279032 : rt__int_size(ArrayType *a, float *size)
     185              : {
     186      4279032 :     *size = (float) ARRNELEMS(a);
     187      4279032 : }
     188              : 
     189              : /* comparison function for isort() and _int_unique() */
     190              : static inline int
     191    331715131 : isort_cmp(const void *a, const void *b, void *arg)
     192              : {
     193    331715131 :     int32       aval = *((const int32 *) a);
     194    331715131 :     int32       bval = *((const int32 *) b);
     195              : 
     196    331715131 :     if (*((bool *) arg))
     197              :     {
     198              :         /* compare for ascending order */
     199    331715125 :         if (aval < bval)
     200    143648159 :             return -1;
     201    188066966 :         if (aval > bval)
     202    186978873 :             return 1;
     203              :     }
     204              :     else
     205              :     {
     206            6 :         if (aval > bval)
     207            4 :             return -1;
     208            2 :         if (aval < bval)
     209            2 :             return 1;
     210              :     }
     211      1088093 :     return 0;
     212              : }
     213              : 
     214              : #define ST_SORT isort
     215              : #define ST_ELEMENT_TYPE int32
     216              : #define ST_COMPARE(a, b, ascending) isort_cmp(a, b, ascending)
     217              : #define ST_COMPARE_ARG_TYPE void
     218              : #define ST_SCOPE
     219              : #define ST_DEFINE
     220              : #include "lib/sort_template.h"
     221              : 
     222              : /* Create a new int array with room for "num" elements */
     223              : ArrayType *
     224      5454096 : new_intArrayType(int num)
     225              : {
     226              :     ArrayType  *r;
     227              :     int         nbytes;
     228              : 
     229              :     /* if no elements, return a zero-dimensional array */
     230      5454096 :     if (num <= 0)
     231              :     {
     232              :         Assert(num == 0);
     233      1410432 :         r = construct_empty_array(INT4OID);
     234      1410432 :         return r;
     235              :     }
     236              : 
     237      4043664 :     nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num;
     238              : 
     239      4043664 :     r = (ArrayType *) palloc0(nbytes);
     240              : 
     241      4043664 :     SET_VARSIZE(r, nbytes);
     242      4043664 :     ARR_NDIM(r) = 1;
     243      4043664 :     r->dataoffset = 0;           /* marker for no null bitmap */
     244      4043664 :     ARR_ELEMTYPE(r) = INT4OID;
     245      4043664 :     ARR_DIMS(r)[0] = num;
     246      4043664 :     ARR_LBOUND(r)[0] = 1;
     247              : 
     248      4043664 :     return r;
     249              : }
     250              : 
     251              : ArrayType *
     252      5098663 : resize_intArrayType(ArrayType *a, int num)
     253              : {
     254              :     int         nbytes;
     255              :     int         i;
     256              : 
     257              :     /* if no elements, return a zero-dimensional array */
     258      5098663 :     if (num <= 0)
     259              :     {
     260              :         Assert(num == 0);
     261          234 :         a = construct_empty_array(INT4OID);
     262          234 :         return a;
     263              :     }
     264              : 
     265      5098429 :     if (num == ARRNELEMS(a))
     266      3962633 :         return a;
     267              : 
     268      1135796 :     nbytes = ARR_DATA_OFFSET(a) + sizeof(int) * num;
     269              : 
     270      1135796 :     a = (ArrayType *) repalloc(a, nbytes);
     271              : 
     272      1135796 :     SET_VARSIZE(a, nbytes);
     273              :     /* usually the array should be 1-D already, but just in case ... */
     274      2271592 :     for (i = 0; i < ARR_NDIM(a); i++)
     275              :     {
     276      1135796 :         ARR_DIMS(a)[i] = num;
     277      1135796 :         num = 1;
     278              :     }
     279      1135796 :     return a;
     280              : }
     281              : 
     282              : ArrayType *
     283        18654 : copy_intArrayType(ArrayType *a)
     284              : {
     285              :     ArrayType  *r;
     286        18654 :     int         n = ARRNELEMS(a);
     287              : 
     288        18654 :     r = new_intArrayType(n);
     289        18654 :     memcpy(ARRPTR(r), ARRPTR(a), n * sizeof(int32));
     290        18654 :     return r;
     291              : }
     292              : 
     293              : /* num for compressed key */
     294              : int
     295        28551 : internal_size(int *a, int len)
     296              : {
     297              :     int         i;
     298        28551 :     int64       size = 0;
     299              : 
     300      6837323 :     for (i = 0; i < len; i += 2)
     301              :     {
     302      6808772 :         if (!i || a[i] != a[i - 1]) /* do not count repeated range */
     303      6808772 :             size += (int64) (a[i + 1]) - (int64) (a[i]) + 1;
     304              :     }
     305              : 
     306        28551 :     if (size > (int64) INT_MAX || size < (int64) INT_MIN)
     307            0 :         return -1;              /* overflow */
     308        28551 :     return (int) size;
     309              : }
     310              : 
     311              : /* unique-ify elements of r in-place ... r must be sorted already */
     312              : ArrayType *
     313      2547779 : _int_unique(ArrayType *r)
     314              : {
     315      2547779 :     int         num = ARRNELEMS(r);
     316      2547779 :     bool        ascending = true;
     317              : 
     318      2547779 :     num = qunique_arg(ARRPTR(r), num, sizeof(int), isort_cmp,
     319              :                       &ascending);
     320              : 
     321      2547779 :     return resize_intArrayType(r, num);
     322              : }
     323              : 
     324              : void
     325            0 : gensign(BITVECP sign, int *a, int len, int siglen)
     326              : {
     327              :     int         i;
     328              : 
     329              :     /* we assume that the sign vector is previously zeroed */
     330            0 :     for (i = 0; i < len; i++)
     331              :     {
     332            0 :         HASH(sign, *a, siglen);
     333            0 :         a++;
     334              :     }
     335            0 : }
     336              : 
     337              : int32
     338            1 : intarray_match_first(ArrayType *a, int32 elem)
     339              : {
     340              :     int32      *aa,
     341              :                 c,
     342              :                 i;
     343              : 
     344            1 :     CHECKARRVALID(a);
     345            1 :     c = ARRNELEMS(a);
     346            1 :     aa = ARRPTR(a);
     347            2 :     for (i = 0; i < c; i++)
     348            2 :         if (aa[i] == elem)
     349            1 :             return (i + 1);
     350            0 :     return 0;
     351              : }
     352              : 
     353              : ArrayType *
     354            4 : intarray_add_elem(ArrayType *a, int32 elem)
     355              : {
     356              :     ArrayType  *result;
     357              :     int32      *r;
     358              :     int32       c;
     359              : 
     360            4 :     CHECKARRVALID(a);
     361            4 :     c = ARRNELEMS(a);
     362            4 :     result = new_intArrayType(c + 1);
     363            4 :     r = ARRPTR(result);
     364            4 :     if (c > 0)
     365            4 :         memcpy(r, ARRPTR(a), c * sizeof(int32));
     366            4 :     r[c] = elem;
     367            4 :     return result;
     368              : }
     369              : 
     370              : ArrayType *
     371            1 : intarray_concat_arrays(ArrayType *a, ArrayType *b)
     372              : {
     373              :     ArrayType  *result;
     374            1 :     int32       ac = ARRNELEMS(a);
     375            1 :     int32       bc = ARRNELEMS(b);
     376              : 
     377            1 :     CHECKARRVALID(a);
     378            1 :     CHECKARRVALID(b);
     379            1 :     result = new_intArrayType(ac + bc);
     380            1 :     if (ac)
     381            1 :         memcpy(ARRPTR(result), ARRPTR(a), ac * sizeof(int32));
     382            1 :     if (bc)
     383            1 :         memcpy(ARRPTR(result) + ac, ARRPTR(b), bc * sizeof(int32));
     384            1 :     return result;
     385              : }
     386              : 
     387              : ArrayType *
     388            1 : int_to_intset(int32 elem)
     389              : {
     390              :     ArrayType  *result;
     391              :     int32      *aa;
     392              : 
     393            1 :     result = new_intArrayType(1);
     394            1 :     aa = ARRPTR(result);
     395            1 :     aa[0] = elem;
     396            1 :     return result;
     397              : }
        

Generated by: LCOV version 2.0-1