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-02-17 17:20:33 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        95009 : 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        95009 :     na = ARRNELEMS(a);
      26        95009 :     nb = ARRNELEMS(b);
      27        95009 :     da = ARRPTR(a);
      28        95009 :     db = ARRPTR(b);
      29              : 
      30        95009 :     i = j = n = 0;
      31       234694 :     while (i < na && j < nb)
      32              :     {
      33       227811 :         if (da[i] < db[j])
      34       132974 :             i++;
      35        94837 :         else if (da[i] == db[j])
      36              :         {
      37         6711 :             n++;
      38         6711 :             i++;
      39         6711 :             j++;
      40              :         }
      41              :         else
      42        88126 :             break;              /* db[j] is not in da */
      43              :     }
      44              : 
      45        95009 :     return (n == nb);
      46              : }
      47              : 
      48              : /* arguments are assumed sorted */
      49              : bool
      50        23311 : 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        23311 :     na = ARRNELEMS(a);
      60        23311 :     nb = ARRNELEMS(b);
      61        23311 :     da = ARRPTR(a);
      62        23311 :     db = ARRPTR(b);
      63              : 
      64        23311 :     i = j = 0;
      65       108659 :     while (i < na && j < nb)
      66              :     {
      67        88237 :         if (da[i] < db[j])
      68        44452 :             i++;
      69        43785 :         else if (da[i] == db[j])
      70         2889 :             return true;
      71              :         else
      72        40896 :             j++;
      73              :     }
      74              : 
      75        20422 :     return false;
      76              : }
      77              : 
      78              : ArrayType *
      79      2246941 : inner_int_union(ArrayType *a, ArrayType *b)
      80              : {
      81      2246941 :     ArrayType  *r = NULL;
      82              : 
      83      2246941 :     CHECKARRVALID(a);
      84      2246941 :     CHECKARRVALID(b);
      85              : 
      86      2246941 :     if (ARRISEMPTY(a) && ARRISEMPTY(b))
      87          133 :         return new_intArrayType(0);
      88      2246808 :     if (ARRISEMPTY(a))
      89        13672 :         r = copy_intArrayType(b);
      90      2246808 :     if (ARRISEMPTY(b))
      91         4355 :         r = copy_intArrayType(a);
      92              : 
      93      2246808 :     if (!r)
      94              :     {
      95      2228781 :         int         na = ARRNELEMS(a),
      96      2228781 :                     nb = ARRNELEMS(b);
      97      2228781 :         int        *da = ARRPTR(a),
      98      2228781 :                    *db = ARRPTR(b);
      99              :         int         i,
     100              :                     j,
     101              :                    *dr;
     102              : 
     103      2228781 :         r = new_intArrayType(na + nb);
     104      2228781 :         dr = ARRPTR(r);
     105              : 
     106              :         /* union */
     107      2228781 :         i = j = 0;
     108     82449807 :         while (i < na && j < nb)
     109              :         {
     110     80221026 :             if (da[i] == db[j])
     111              :             {
     112      5247407 :                 *dr++ = da[i++];
     113      5247407 :                 j++;
     114              :             }
     115     74973619 :             else if (da[i] < db[j])
     116     63154909 :                 *dr++ = da[i++];
     117              :             else
     118     11818710 :                 *dr++ = db[j++];
     119              :         }
     120              : 
     121      7719244 :         while (i < na)
     122      5490463 :             *dr++ = da[i++];
     123      4256553 :         while (j < nb)
     124      2027772 :             *dr++ = db[j++];
     125              : 
     126      2228781 :         r = resize_intArrayType(r, dr - ARRPTR(r));
     127              :     }
     128              : 
     129      2246808 :     if (ARRNELEMS(r) > 1)
     130      2246801 :         r = _int_unique(r);
     131              : 
     132      2246808 :     return r;
     133              : }
     134              : 
     135              : ArrayType *
     136      1801392 : 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      1801392 :     if (ARRISEMPTY(a) || ARRISEMPTY(b))
     149        17550 :         return new_intArrayType(0);
     150              : 
     151      1783842 :     na = ARRNELEMS(a);
     152      1783842 :     nb = ARRNELEMS(b);
     153      1783842 :     da = ARRPTR(a);
     154      1783842 :     db = ARRPTR(b);
     155      1783842 :     r = new_intArrayType(Min(na, nb));
     156      1783842 :     dr = ARRPTR(r);
     157              : 
     158      1783842 :     i = j = k = 0;
     159     22112580 :     while (i < na && j < nb)
     160              :     {
     161     20328738 :         if (da[i] < db[j])
     162      9325987 :             i++;
     163     11002751 :         else if (da[i] == db[j])
     164              :         {
     165      1831832 :             if (k == 0 || dr[k - 1] != db[j])
     166      1831832 :                 dr[k++] = db[j];
     167      1831832 :             i++;
     168      1831832 :             j++;
     169              :         }
     170              :         else
     171      9170919 :             j++;
     172              :     }
     173              : 
     174      1783842 :     if (k == 0)
     175              :     {
     176      1413505 :         pfree(r);
     177      1413505 :         return new_intArrayType(0);
     178              :     }
     179              :     else
     180       370337 :         return resize_intArrayType(r, k);
     181              : }
     182              : 
     183              : void
     184      4362510 : rt__int_size(ArrayType *a, float *size)
     185              : {
     186      4362510 :     *size = (float) ARRNELEMS(a);
     187      4362510 : }
     188              : 
     189              : /* comparison function for isort() and _int_unique() */
     190              : static inline int
     191    337892148 : isort_cmp(const void *a, const void *b, void *arg)
     192              : {
     193    337892148 :     int32       aval = *((const int32 *) a);
     194    337892148 :     int32       bval = *((const int32 *) b);
     195              : 
     196    337892148 :     if (*((bool *) arg))
     197              :     {
     198              :         /* compare for ascending order */
     199    337892142 :         if (aval < bval)
     200    145697246 :             return -1;
     201    192194896 :         if (aval > bval)
     202    191089548 :             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      1105348 :     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      5546788 : new_intArrayType(int num)
     225              : {
     226              :     ArrayType  *r;
     227              :     int         nbytes;
     228              : 
     229              :     /* if no elements, return a zero-dimensional array */
     230      5546788 :     if (num <= 0)
     231              :     {
     232              :         Assert(num == 0);
     233      1431188 :         r = construct_empty_array(INT4OID);
     234      1431188 :         return r;
     235              :     }
     236              : 
     237      4115600 :     nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num;
     238              : 
     239      4115600 :     r = (ArrayType *) palloc0(nbytes);
     240              : 
     241      4115600 :     SET_VARSIZE(r, nbytes);
     242      4115600 :     ARR_NDIM(r) = 1;
     243      4115600 :     r->dataoffset = 0;           /* marker for no null bitmap */
     244      4115600 :     ARR_ELEMTYPE(r) = INT4OID;
     245      4115600 :     ARR_DIMS(r)[0] = num;
     246      4115600 :     ARR_LBOUND(r)[0] = 1;
     247              : 
     248      4115600 :     return r;
     249              : }
     250              : 
     251              : ArrayType *
     252      5191166 : resize_intArrayType(ArrayType *a, int num)
     253              : {
     254              :     int         nbytes;
     255              :     int         i;
     256              : 
     257              :     /* if no elements, return a zero-dimensional array */
     258      5191166 :     if (num <= 0)
     259              :     {
     260              :         Assert(num == 0);
     261          234 :         a = construct_empty_array(INT4OID);
     262          234 :         return a;
     263              :     }
     264              : 
     265      5190932 :     if (num == ARRNELEMS(a))
     266      4025537 :         return a;
     267              : 
     268      1165395 :     nbytes = ARR_DATA_OFFSET(a) + sizeof(int) * num;
     269              : 
     270      1165395 :     a = (ArrayType *) repalloc(a, nbytes);
     271              : 
     272      1165395 :     SET_VARSIZE(a, nbytes);
     273              :     /* usually the array should be 1-D already, but just in case ... */
     274      2330790 :     for (i = 0; i < ARR_NDIM(a); i++)
     275              :     {
     276      1165395 :         ARR_DIMS(a)[i] = num;
     277      1165395 :         num = 1;
     278              :     }
     279      1165395 :     return a;
     280              : }
     281              : 
     282              : ArrayType *
     283        19285 : copy_intArrayType(ArrayType *a)
     284              : {
     285              :     ArrayType  *r;
     286        19285 :     int         n = ARRNELEMS(a);
     287              : 
     288        19285 :     r = new_intArrayType(n);
     289        19285 :     memcpy(ARRPTR(r), ARRPTR(a), n * sizeof(int32));
     290        19285 :     return r;
     291              : }
     292              : 
     293              : /* num for compressed key */
     294              : int
     295        27692 : internal_size(int *a, int len)
     296              : {
     297              :     int         i;
     298        27692 :     int64       size = 0;
     299              : 
     300      6612396 :     for (i = 0; i < len; i += 2)
     301              :     {
     302      6584704 :         if (!i || a[i] != a[i - 1]) /* do not count repeated range */
     303      6584704 :             size += (int64) (a[i + 1]) - (int64) (a[i]) + 1;
     304              :     }
     305              : 
     306        27692 :     if (size > (int64) INT_MAX || size < (int64) INT_MIN)
     307            0 :         return -1;              /* overflow */
     308        27692 :     return (int) size;
     309              : }
     310              : 
     311              : /* unique-ify elements of r in-place ... r must be sorted already */
     312              : ArrayType *
     313      2589078 : _int_unique(ArrayType *r)
     314              : {
     315      2589078 :     int         num = ARRNELEMS(r);
     316      2589078 :     bool        ascending = true;
     317              : 
     318      2589078 :     num = qunique_arg(ARRPTR(r), num, sizeof(int), isort_cmp,
     319              :                       &ascending);
     320              : 
     321      2589078 :     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