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-10 06:14:44 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        92131 : 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        92131 :     na = ARRNELEMS(a);
      26        92131 :     nb = ARRNELEMS(b);
      27        92131 :     da = ARRPTR(a);
      28        92131 :     db = ARRPTR(b);
      29              : 
      30        92131 :     i = j = n = 0;
      31       228835 :     while (i < na && j < nb)
      32              :     {
      33       222033 :         if (da[i] < db[j])
      34       130139 :             i++;
      35        91894 :         else if (da[i] == db[j])
      36              :         {
      37         6565 :             n++;
      38         6565 :             i++;
      39         6565 :             j++;
      40              :         }
      41              :         else
      42        85329 :             break;              /* db[j] is not in da */
      43              :     }
      44              : 
      45        92131 :     return (n == nb);
      46              : }
      47              : 
      48              : /* arguments are assumed sorted */
      49              : bool
      50        23840 : 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        23840 :     na = ARRNELEMS(a);
      60        23840 :     nb = ARRNELEMS(b);
      61        23840 :     da = ARRPTR(a);
      62        23840 :     db = ARRPTR(b);
      63              : 
      64        23840 :     i = j = 0;
      65       111533 :     while (i < na && j < nb)
      66              :     {
      67        90617 :         if (da[i] < db[j])
      68        45797 :             i++;
      69        44820 :         else if (da[i] == db[j])
      70         2924 :             return true;
      71              :         else
      72        41896 :             j++;
      73              :     }
      74              : 
      75        20916 :     return false;
      76              : }
      77              : 
      78              : ArrayType *
      79      2213313 : inner_int_union(ArrayType *a, ArrayType *b)
      80              : {
      81      2213313 :     ArrayType  *r = NULL;
      82              : 
      83      2213313 :     CHECKARRVALID(a);
      84      2213313 :     CHECKARRVALID(b);
      85              : 
      86      2213313 :     if (ARRISEMPTY(a) && ARRISEMPTY(b))
      87          177 :         return new_intArrayType(0);
      88      2213136 :     if (ARRISEMPTY(a))
      89        12779 :         r = copy_intArrayType(b);
      90      2213136 :     if (ARRISEMPTY(b))
      91         4215 :         r = copy_intArrayType(a);
      92              : 
      93      2213136 :     if (!r)
      94              :     {
      95      2196142 :         int         na = ARRNELEMS(a),
      96      2196142 :                     nb = ARRNELEMS(b);
      97      2196142 :         int        *da = ARRPTR(a),
      98      2196142 :                    *db = ARRPTR(b);
      99              :         int         i,
     100              :                     j,
     101              :                    *dr;
     102              : 
     103      2196142 :         r = new_intArrayType(na + nb);
     104      2196142 :         dr = ARRPTR(r);
     105              : 
     106              :         /* union */
     107      2196142 :         i = j = 0;
     108     82184550 :         while (i < na && j < nb)
     109              :         {
     110     79988408 :             if (da[i] == db[j])
     111              :             {
     112      5131025 :                 *dr++ = da[i++];
     113      5131025 :                 j++;
     114              :             }
     115     74857383 :             else if (da[i] < db[j])
     116     63291867 :                 *dr++ = da[i++];
     117              :             else
     118     11565516 :                 *dr++ = db[j++];
     119              :         }
     120              : 
     121      7776301 :         while (i < na)
     122      5580159 :             *dr++ = da[i++];
     123      4144946 :         while (j < nb)
     124      1948804 :             *dr++ = db[j++];
     125              : 
     126      2196142 :         r = resize_intArrayType(r, dr - ARRPTR(r));
     127              :     }
     128              : 
     129      2213136 :     if (ARRNELEMS(r) > 1)
     130      2213126 :         r = _int_unique(r);
     131              : 
     132      2213136 :     return r;
     133              : }
     134              : 
     135              : ArrayType *
     136      1771493 : 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      1771493 :     if (ARRISEMPTY(a) || ARRISEMPTY(b))
     149        16599 :         return new_intArrayType(0);
     150              : 
     151      1754894 :     na = ARRNELEMS(a);
     152      1754894 :     nb = ARRNELEMS(b);
     153      1754894 :     da = ARRPTR(a);
     154      1754894 :     db = ARRPTR(b);
     155      1754894 :     r = new_intArrayType(Min(na, nb));
     156      1754894 :     dr = ARRPTR(r);
     157              : 
     158      1754894 :     i = j = k = 0;
     159     21672343 :     while (i < na && j < nb)
     160              :     {
     161     19917449 :         if (da[i] < db[j])
     162      9144309 :             i++;
     163     10773140 :         else if (da[i] == db[j])
     164              :         {
     165      1779715 :             if (k == 0 || dr[k - 1] != db[j])
     166      1779715 :                 dr[k++] = db[j];
     167      1779715 :             i++;
     168      1779715 :             j++;
     169              :         }
     170              :         else
     171      8993425 :             j++;
     172              :     }
     173              : 
     174      1754894 :     if (k == 0)
     175              :     {
     176      1389869 :         pfree(r);
     177      1389869 :         return new_intArrayType(0);
     178              :     }
     179              :     else
     180       365025 :         return resize_intArrayType(r, k);
     181              : }
     182              : 
     183              : void
     184      4297610 : rt__int_size(ArrayType *a, float *size)
     185              : {
     186      4297610 :     *size = (float) ARRNELEMS(a);
     187      4297610 : }
     188              : 
     189              : /* comparison function for isort() and _int_unique() */
     190              : static inline int
     191    350771104 : isort_cmp(const void *a, const void *b, void *arg)
     192              : {
     193    350771104 :     int32       aval = *((const int32 *) a);
     194    350771104 :     int32       bval = *((const int32 *) b);
     195              : 
     196    350771104 :     if (*((bool *) arg))
     197              :     {
     198              :         /* compare for ascending order */
     199    350771098 :         if (aval < bval)
     200    153516807 :             return -1;
     201    197254291 :         if (aval > bval)
     202    196132014 :             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      1122277 :     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      5462753 : new_intArrayType(int num)
     225              : {
     226              :     ArrayType  *r;
     227              :     int         nbytes;
     228              : 
     229              :     /* if no elements, return a zero-dimensional array */
     230      5462753 :     if (num <= 0)
     231              :     {
     232              :         Assert(num == 0);
     233      1406645 :         r = construct_empty_array(INT4OID);
     234      1406645 :         return r;
     235              :     }
     236              : 
     237      4056108 :     nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num;
     238              : 
     239      4056108 :     r = (ArrayType *) palloc0(nbytes);
     240              : 
     241      4056108 :     SET_VARSIZE(r, nbytes);
     242      4056108 :     ARR_NDIM(r) = 1;
     243      4056108 :     r->dataoffset = 0;           /* marker for no null bitmap */
     244      4056108 :     ARR_ELEMTYPE(r) = INT4OID;
     245      4056108 :     ARR_DIMS(r)[0] = num;
     246      4056108 :     ARR_LBOUND(r)[0] = 1;
     247              : 
     248      4056108 :     return r;
     249              : }
     250              : 
     251              : ArrayType *
     252      5117064 : resize_intArrayType(ArrayType *a, int num)
     253              : {
     254              :     int         nbytes;
     255              :     int         i;
     256              : 
     257              :     /* if no elements, return a zero-dimensional array */
     258      5117064 :     if (num <= 0)
     259              :     {
     260              :         Assert(num == 0);
     261          234 :         a = construct_empty_array(INT4OID);
     262          234 :         return a;
     263              :     }
     264              : 
     265      5116830 :     if (num == ARRNELEMS(a))
     266      3963805 :         return a;
     267              : 
     268      1153025 :     nbytes = ARR_DATA_OFFSET(a) + sizeof(int) * num;
     269              : 
     270      1153025 :     a = (ArrayType *) repalloc(a, nbytes);
     271              : 
     272      1153025 :     SET_VARSIZE(a, nbytes);
     273              :     /* usually the array should be 1-D already, but just in case ... */
     274      2306050 :     for (i = 0; i < ARR_NDIM(a); i++)
     275              :     {
     276      1153025 :         ARR_DIMS(a)[i] = num;
     277      1153025 :         num = 1;
     278              :     }
     279      1153025 :     return a;
     280              : }
     281              : 
     282              : ArrayType *
     283        18228 : copy_intArrayType(ArrayType *a)
     284              : {
     285              :     ArrayType  *r;
     286        18228 :     int         n = ARRNELEMS(a);
     287              : 
     288        18228 :     r = new_intArrayType(n);
     289        18228 :     memcpy(ARRPTR(r), ARRPTR(a), n * sizeof(int32));
     290        18228 :     return r;
     291              : }
     292              : 
     293              : /* num for compressed key */
     294              : int
     295        30060 : internal_size(int *a, int len)
     296              : {
     297              :     int         i;
     298        30060 :     int64       size = 0;
     299              : 
     300      7127140 :     for (i = 0; i < len; i += 2)
     301              :     {
     302      7097080 :         if (!i || a[i] != a[i - 1]) /* do not count repeated range */
     303      7097080 :             size += (int64) (a[i + 1]) - (int64) (a[i]) + 1;
     304              :     }
     305              : 
     306        30060 :     if (size > (int64) INT_MAX || size < (int64) INT_MIN)
     307            0 :         return -1;              /* overflow */
     308        30060 :     return (int) size;
     309              : }
     310              : 
     311              : /* unique-ify elements of r in-place ... r must be sorted already */
     312              : ArrayType *
     313      2553013 : _int_unique(ArrayType *r)
     314              : {
     315      2553013 :     int         num = ARRNELEMS(r);
     316      2553013 :     bool        ascending = true;
     317              : 
     318      2553013 :     num = qunique_arg(ARRPTR(r), num, sizeof(int), isort_cmp,
     319              :                       &ascending);
     320              : 
     321      2553013 :     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