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-28 03:14:59 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        96506 : 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        96506 :     na = ARRNELEMS(a);
      26        96506 :     nb = ARRNELEMS(b);
      27        96506 :     da = ARRPTR(a);
      28        96506 :     db = ARRPTR(b);
      29              : 
      30        96506 :     i = j = n = 0;
      31       240205 :     while (i < na && j < nb)
      32              :     {
      33       233259 :         if (da[i] < db[j])
      34       136685 :             i++;
      35        96574 :         else if (da[i] == db[j])
      36              :         {
      37         7014 :             n++;
      38         7014 :             i++;
      39         7014 :             j++;
      40              :         }
      41              :         else
      42        89560 :             break;              /* db[j] is not in da */
      43              :     }
      44              : 
      45        96506 :     return (n == nb);
      46              : }
      47              : 
      48              : /* arguments are assumed sorted */
      49              : bool
      50        23471 : 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        23471 :     na = ARRNELEMS(a);
      60        23471 :     nb = ARRNELEMS(b);
      61        23471 :     da = ARRPTR(a);
      62        23471 :     db = ARRPTR(b);
      63              : 
      64        23471 :     i = j = 0;
      65       110262 :     while (i < na && j < nb)
      66              :     {
      67        89731 :         if (da[i] < db[j])
      68        45696 :             i++;
      69        44035 :         else if (da[i] == db[j])
      70         2940 :             return true;
      71              :         else
      72        41095 :             j++;
      73              :     }
      74              : 
      75        20531 :     return false;
      76              : }
      77              : 
      78              : ArrayType *
      79      2257711 : inner_int_union(ArrayType *a, ArrayType *b)
      80              : {
      81      2257711 :     ArrayType  *r = NULL;
      82              : 
      83      2257711 :     CHECKARRVALID(a);
      84      2257711 :     CHECKARRVALID(b);
      85              : 
      86      2257711 :     if (ARRISEMPTY(a) && ARRISEMPTY(b))
      87          198 :         return new_intArrayType(0);
      88      2257513 :     if (ARRISEMPTY(a))
      89        14008 :         r = copy_intArrayType(b);
      90      2257513 :     if (ARRISEMPTY(b))
      91         4708 :         r = copy_intArrayType(a);
      92              : 
      93      2257513 :     if (!r)
      94              :     {
      95      2238797 :         int         na = ARRNELEMS(a),
      96      2238797 :                     nb = ARRNELEMS(b);
      97      2238797 :         int        *da = ARRPTR(a),
      98      2238797 :                    *db = ARRPTR(b);
      99              :         int         i,
     100              :                     j,
     101              :                    *dr;
     102              : 
     103      2238797 :         r = new_intArrayType(na + nb);
     104      2238797 :         dr = ARRPTR(r);
     105              : 
     106              :         /* union */
     107      2238797 :         i = j = 0;
     108     85186419 :         while (i < na && j < nb)
     109              :         {
     110     82947622 :             if (da[i] == db[j])
     111              :             {
     112      5461976 :                 *dr++ = da[i++];
     113      5461976 :                 j++;
     114              :             }
     115     77485646 :             else if (da[i] < db[j])
     116     65294257 :                 *dr++ = da[i++];
     117              :             else
     118     12191389 :                 *dr++ = db[j++];
     119              :         }
     120              : 
     121      7767154 :         while (i < na)
     122      5528357 :             *dr++ = da[i++];
     123      4281638 :         while (j < nb)
     124      2042841 :             *dr++ = db[j++];
     125              : 
     126      2238797 :         r = resize_intArrayType(r, dr - ARRPTR(r));
     127              :     }
     128              : 
     129      2257513 :     if (ARRNELEMS(r) > 1)
     130      2257498 :         r = _int_unique(r);
     131              : 
     132      2257513 :     return r;
     133              : }
     134              : 
     135              : ArrayType *
     136      1803497 : 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      1803497 :     if (ARRISEMPTY(a) || ARRISEMPTY(b))
     149        18279 :         return new_intArrayType(0);
     150              : 
     151      1785218 :     na = ARRNELEMS(a);
     152      1785218 :     nb = ARRNELEMS(b);
     153      1785218 :     da = ARRPTR(a);
     154      1785218 :     db = ARRPTR(b);
     155      1785218 :     r = new_intArrayType(Min(na, nb));
     156      1785218 :     dr = ARRPTR(r);
     157              : 
     158      1785218 :     i = j = k = 0;
     159     22693110 :     while (i < na && j < nb)
     160              :     {
     161     20907892 :         if (da[i] < db[j])
     162      9559209 :             i++;
     163     11348683 :         else if (da[i] == db[j])
     164              :         {
     165      1928329 :             if (k == 0 || dr[k - 1] != db[j])
     166      1928329 :                 dr[k++] = db[j];
     167      1928329 :             i++;
     168      1928329 :             j++;
     169              :         }
     170              :         else
     171      9420354 :             j++;
     172              :     }
     173              : 
     174      1785218 :     if (k == 0)
     175              :     {
     176      1414842 :         pfree(r);
     177      1414842 :         return new_intArrayType(0);
     178              :     }
     179              :     else
     180       370376 :         return resize_intArrayType(r, k);
     181              : }
     182              : 
     183              : void
     184      4382524 : rt__int_size(ArrayType *a, float *size)
     185              : {
     186      4382524 :     *size = (float) ARRNELEMS(a);
     187      4382524 : }
     188              : 
     189              : /* comparison function for isort() and _int_unique() */
     190              : static inline int
     191    346373211 : isort_cmp(const void *a, const void *b, void *arg)
     192              : {
     193    346373211 :     int32       aval = *((const int32 *) a);
     194    346373211 :     int32       bval = *((const int32 *) b);
     195              : 
     196    346373211 :     if (*((bool *) arg))
     197              :     {
     198              :         /* compare for ascending order */
     199    346373205 :         if (aval < bval)
     200    149150892 :             return -1;
     201    197222313 :         if (aval > bval)
     202    196112027 :             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      1110286 :     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      5562749 : new_intArrayType(int num)
     225              : {
     226              :     ArrayType  *r;
     227              :     int         nbytes;
     228              : 
     229              :     /* if no elements, return a zero-dimensional array */
     230      5562749 :     if (num <= 0)
     231              :     {
     232              :         Assert(num == 0);
     233      1433319 :         r = construct_empty_array(INT4OID);
     234      1433319 :         return r;
     235              :     }
     236              : 
     237      4129430 :     nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num;
     238              : 
     239      4129430 :     r = (ArrayType *) palloc0(nbytes);
     240              : 
     241      4129430 :     SET_VARSIZE(r, nbytes);
     242      4129430 :     ARR_NDIM(r) = 1;
     243      4129430 :     r->dataoffset = 0;           /* marker for no null bitmap */
     244      4129430 :     ARR_ELEMTYPE(r) = INT4OID;
     245      4129430 :     ARR_DIMS(r)[0] = num;
     246      4129430 :     ARR_LBOUND(r)[0] = 1;
     247              : 
     248      4129430 :     return r;
     249              : }
     250              : 
     251              : ArrayType *
     252      5213701 : resize_intArrayType(ArrayType *a, int num)
     253              : {
     254              :     int         nbytes;
     255              :     int         i;
     256              : 
     257              :     /* if no elements, return a zero-dimensional array */
     258      5213701 :     if (num <= 0)
     259              :     {
     260              :         Assert(num == 0);
     261          234 :         a = construct_empty_array(INT4OID);
     262          234 :         return a;
     263              :     }
     264              : 
     265      5213467 :     if (num == ARRNELEMS(a))
     266      4043515 :         return a;
     267              : 
     268      1169952 :     nbytes = ARR_DATA_OFFSET(a) + sizeof(int) * num;
     269              : 
     270      1169952 :     a = (ArrayType *) repalloc(a, nbytes);
     271              : 
     272      1169952 :     SET_VARSIZE(a, nbytes);
     273              :     /* usually the array should be 1-D already, but just in case ... */
     274      2339904 :     for (i = 0; i < ARR_NDIM(a); i++)
     275              :     {
     276      1169952 :         ARR_DIMS(a)[i] = num;
     277      1169952 :         num = 1;
     278              :     }
     279      1169952 :     return a;
     280              : }
     281              : 
     282              : ArrayType *
     283        20016 : copy_intArrayType(ArrayType *a)
     284              : {
     285              :     ArrayType  *r;
     286        20016 :     int         n = ARRNELEMS(a);
     287              : 
     288        20016 :     r = new_intArrayType(n);
     289        20016 :     memcpy(ARRPTR(r), ARRPTR(a), n * sizeof(int32));
     290        20016 :     return r;
     291              : }
     292              : 
     293              : /* num for compressed key */
     294              : int
     295        29582 : internal_size(int *a, int len)
     296              : {
     297              :     int         i;
     298        29582 :     int64       size = 0;
     299              : 
     300      7006358 :     for (i = 0; i < len; i += 2)
     301              :     {
     302      6976776 :         if (!i || a[i] != a[i - 1]) /* do not count repeated range */
     303      6976776 :             size += (int64) (a[i + 1]) - (int64) (a[i]) + 1;
     304              :     }
     305              : 
     306        29582 :     if (size > (int64) INT_MAX || size < (int64) INT_MIN)
     307            0 :         return -1;              /* overflow */
     308        29582 :     return (int) size;
     309              : }
     310              : 
     311              : /* unique-ify elements of r in-place ... r must be sorted already */
     312              : ArrayType *
     313      2601740 : _int_unique(ArrayType *r)
     314              : {
     315      2601740 :     int         num = ARRNELEMS(r);
     316      2601740 :     bool        ascending = true;
     317              : 
     318      2601740 :     num = qunique_arg(ARRPTR(r), num, sizeof(int), isort_cmp,
     319              :                       &ascending);
     320              : 
     321      2601740 :     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