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-03-13 06:15:19 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        97077 : 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        97077 :     na = ARRNELEMS(a);
      26        97077 :     nb = ARRNELEMS(b);
      27        97077 :     da = ARRPTR(a);
      28        97077 :     db = ARRPTR(b);
      29              : 
      30        97077 :     i = j = n = 0;
      31       240976 :     while (i < na && j < nb)
      32              :     {
      33       233904 :         if (da[i] < db[j])
      34       136725 :             i++;
      35        97179 :         else if (da[i] == db[j])
      36              :         {
      37         7174 :             n++;
      38         7174 :             i++;
      39         7174 :             j++;
      40              :         }
      41              :         else
      42        90005 :             break;              /* db[j] is not in da */
      43              :     }
      44              : 
      45        97077 :     return (n == nb);
      46              : }
      47              : 
      48              : /* arguments are assumed sorted */
      49              : bool
      50        23803 : 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        23803 :     na = ARRNELEMS(a);
      60        23803 :     nb = ARRNELEMS(b);
      61        23803 :     da = ARRPTR(a);
      62        23803 :     db = ARRPTR(b);
      63              : 
      64        23803 :     i = j = 0;
      65       110633 :     while (i < na && j < nb)
      66              :     {
      67        89735 :         if (da[i] < db[j])
      68        45025 :             i++;
      69        44710 :         else if (da[i] == db[j])
      70         2905 :             return true;
      71              :         else
      72        41805 :             j++;
      73              :     }
      74              : 
      75        20898 :     return false;
      76              : }
      77              : 
      78              : ArrayType *
      79      2176821 : inner_int_union(ArrayType *a, ArrayType *b)
      80              : {
      81      2176821 :     ArrayType  *r = NULL;
      82              : 
      83      2176821 :     CHECKARRVALID(a);
      84      2176821 :     CHECKARRVALID(b);
      85              : 
      86      2176821 :     if (ARRISEMPTY(a) && ARRISEMPTY(b))
      87          162 :         return new_intArrayType(0);
      88      2176659 :     if (ARRISEMPTY(a))
      89        13020 :         r = copy_intArrayType(b);
      90      2176659 :     if (ARRISEMPTY(b))
      91         4177 :         r = copy_intArrayType(a);
      92              : 
      93      2176659 :     if (!r)
      94              :     {
      95      2159462 :         int         na = ARRNELEMS(a),
      96      2159462 :                     nb = ARRNELEMS(b);
      97      2159462 :         int        *da = ARRPTR(a),
      98      2159462 :                    *db = ARRPTR(b);
      99              :         int         i,
     100              :                     j,
     101              :                    *dr;
     102              : 
     103      2159462 :         r = new_intArrayType(na + nb);
     104      2159462 :         dr = ARRPTR(r);
     105              : 
     106              :         /* union */
     107      2159462 :         i = j = 0;
     108     82550423 :         while (i < na && j < nb)
     109              :         {
     110     80390961 :             if (da[i] == db[j])
     111              :             {
     112      5196755 :                 *dr++ = da[i++];
     113      5196755 :                 j++;
     114              :             }
     115     75194206 :             else if (da[i] < db[j])
     116     63577474 :                 *dr++ = da[i++];
     117              :             else
     118     11616732 :                 *dr++ = db[j++];
     119              :         }
     120              : 
     121      7690560 :         while (i < na)
     122      5531098 :             *dr++ = da[i++];
     123      4101981 :         while (j < nb)
     124      1942519 :             *dr++ = db[j++];
     125              : 
     126      2159462 :         r = resize_intArrayType(r, dr - ARRPTR(r));
     127              :     }
     128              : 
     129      2176659 :     if (ARRNELEMS(r) > 1)
     130      2176652 :         r = _int_unique(r);
     131              : 
     132      2176659 :     return r;
     133              : }
     134              : 
     135              : ArrayType *
     136      1732666 : 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      1732666 :     if (ARRISEMPTY(a) || ARRISEMPTY(b))
     149        16781 :         return new_intArrayType(0);
     150              : 
     151      1715885 :     na = ARRNELEMS(a);
     152      1715885 :     nb = ARRNELEMS(b);
     153      1715885 :     da = ARRPTR(a);
     154      1715885 :     db = ARRPTR(b);
     155      1715885 :     r = new_intArrayType(Min(na, nb));
     156      1715885 :     dr = ARRPTR(r);
     157              : 
     158      1715885 :     i = j = k = 0;
     159     21611610 :     while (i < na && j < nb)
     160              :     {
     161     19895725 :         if (da[i] < db[j])
     162      9113008 :             i++;
     163     10782717 :         else if (da[i] == db[j])
     164              :         {
     165      1800281 :             if (k == 0 || dr[k - 1] != db[j])
     166      1800281 :                 dr[k++] = db[j];
     167      1800281 :             i++;
     168      1800281 :             j++;
     169              :         }
     170              :         else
     171      8982436 :             j++;
     172              :     }
     173              : 
     174      1715885 :     if (k == 0)
     175              :     {
     176      1363222 :         pfree(r);
     177      1363222 :         return new_intArrayType(0);
     178              :     }
     179              :     else
     180       352663 :         return resize_intArrayType(r, k);
     181              : }
     182              : 
     183              : void
     184      4226220 : rt__int_size(ArrayType *a, float *size)
     185              : {
     186      4226220 :     *size = (float) ARRNELEMS(a);
     187      4226220 : }
     188              : 
     189              : /* comparison function for isort() and _int_unique() */
     190              : static inline int
     191    343225630 : isort_cmp(const void *a, const void *b, void *arg)
     192              : {
     193    343225630 :     int32       aval = *((const int32 *) a);
     194    343225630 :     int32       bval = *((const int32 *) b);
     195              : 
     196    343225630 :     if (*((bool *) arg))
     197              :     {
     198              :         /* compare for ascending order */
     199    343225624 :         if (aval < bval)
     200    148717589 :             return -1;
     201    194508035 :         if (aval > bval)
     202    193387672 :             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      1120363 :     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      5358891 : new_intArrayType(int num)
     225              : {
     226              :     ArrayType  *r;
     227              :     int         nbytes;
     228              : 
     229              :     /* if no elements, return a zero-dimensional array */
     230      5358891 :     if (num <= 0)
     231              :     {
     232              :         Assert(num == 0);
     233      1380165 :         r = construct_empty_array(INT4OID);
     234      1380165 :         return r;
     235              :     }
     236              : 
     237      3978726 :     nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num;
     238              : 
     239      3978726 :     r = (ArrayType *) palloc0(nbytes);
     240              : 
     241      3978726 :     SET_VARSIZE(r, nbytes);
     242      3978726 :     ARR_NDIM(r) = 1;
     243      3978726 :     r->dataoffset = 0;           /* marker for no null bitmap */
     244      3978726 :     ARR_ELEMTYPE(r) = INT4OID;
     245      3978726 :     ARR_DIMS(r)[0] = num;
     246      3978726 :     ARR_LBOUND(r)[0] = 1;
     247              : 
     248      3978726 :     return r;
     249              : }
     250              : 
     251              : ArrayType *
     252      5037669 : resize_intArrayType(ArrayType *a, int num)
     253              : {
     254              :     int         nbytes;
     255              :     int         i;
     256              : 
     257              :     /* if no elements, return a zero-dimensional array */
     258      5037669 :     if (num <= 0)
     259              :     {
     260              :         Assert(num == 0);
     261          234 :         a = construct_empty_array(INT4OID);
     262          234 :         return a;
     263              :     }
     264              : 
     265      5037435 :     if (num == ARRNELEMS(a))
     266      3907072 :         return a;
     267              : 
     268      1130363 :     nbytes = ARR_DATA_OFFSET(a) + sizeof(int) * num;
     269              : 
     270      1130363 :     a = (ArrayType *) repalloc(a, nbytes);
     271              : 
     272      1130363 :     SET_VARSIZE(a, nbytes);
     273              :     /* usually the array should be 1-D already, but just in case ... */
     274      2260726 :     for (i = 0; i < ARR_NDIM(a); i++)
     275              :     {
     276      1130363 :         ARR_DIMS(a)[i] = num;
     277      1130363 :         num = 1;
     278              :     }
     279      1130363 :     return a;
     280              : }
     281              : 
     282              : ArrayType *
     283        18441 : copy_intArrayType(ArrayType *a)
     284              : {
     285              :     ArrayType  *r;
     286        18441 :     int         n = ARRNELEMS(a);
     287              : 
     288        18441 :     r = new_intArrayType(n);
     289        18441 :     memcpy(ARRPTR(r), ARRPTR(a), n * sizeof(int32));
     290        18441 :     return r;
     291              : }
     292              : 
     293              : /* num for compressed key */
     294              : int
     295        28491 : internal_size(int *a, int len)
     296              : {
     297              :     int         i;
     298        28491 :     int64       size = 0;
     299              : 
     300      6784751 :     for (i = 0; i < len; i += 2)
     301              :     {
     302      6756260 :         if (!i || a[i] != a[i - 1]) /* do not count repeated range */
     303      6756260 :             size += (int64) (a[i + 1]) - (int64) (a[i]) + 1;
     304              :     }
     305              : 
     306        28491 :     if (size > (int64) INT_MAX || size < (int64) INT_MIN)
     307            0 :         return -1;              /* overflow */
     308        28491 :     return (int) size;
     309              : }
     310              : 
     311              : /* unique-ify elements of r in-place ... r must be sorted already */
     312              : ArrayType *
     313      2522744 : _int_unique(ArrayType *r)
     314              : {
     315      2522744 :     int         num = ARRNELEMS(r);
     316      2522744 :     bool        ascending = true;
     317              : 
     318      2522744 :     num = qunique_arg(ARRPTR(r), num, sizeof(int), isort_cmp,
     319              :                       &ascending);
     320              : 
     321      2522744 :     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