LCOV - code coverage report
Current view: top level - contrib/intarray - _int_tool.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 175 182 96.2 %
Date: 2025-02-22 07:14:56 Functions: 15 16 93.8 %
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      193590 : 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      193590 :     na = ARRNELEMS(a);
      26      193590 :     nb = ARRNELEMS(b);
      27      193590 :     da = ARRPTR(a);
      28      193590 :     db = ARRPTR(b);
      29             : 
      30      193590 :     i = j = n = 0;
      31      481880 :     while (i < na && j < nb)
      32             :     {
      33      467844 :         if (da[i] < db[j])
      34      274114 :             i++;
      35      193730 :         else if (da[i] == db[j])
      36             :         {
      37       14176 :             n++;
      38       14176 :             i++;
      39       14176 :             j++;
      40             :         }
      41             :         else
      42      179554 :             break;              /* db[j] is not in da */
      43             :     }
      44             : 
      45      193590 :     return (n == nb);
      46             : }
      47             : 
      48             : /* arguments are assumed sorted */
      49             : bool
      50       47266 : 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       47266 :     na = ARRNELEMS(a);
      60       47266 :     nb = ARRNELEMS(b);
      61       47266 :     da = ARRPTR(a);
      62       47266 :     db = ARRPTR(b);
      63             : 
      64       47266 :     i = j = 0;
      65      222086 :     while (i < na && j < nb)
      66             :     {
      67      180692 :         if (da[i] < db[j])
      68       92004 :             i++;
      69       88688 :         else if (da[i] == db[j])
      70        5872 :             return true;
      71             :         else
      72       82816 :             j++;
      73             :     }
      74             : 
      75       41394 :     return false;
      76             : }
      77             : 
      78             : ArrayType *
      79     4443020 : inner_int_union(ArrayType *a, ArrayType *b)
      80             : {
      81     4443020 :     ArrayType  *r = NULL;
      82             : 
      83     4443020 :     CHECKARRVALID(a);
      84     4443020 :     CHECKARRVALID(b);
      85             : 
      86     4443020 :     if (ARRISEMPTY(a) && ARRISEMPTY(b))
      87         410 :         return new_intArrayType(0);
      88     4442610 :     if (ARRISEMPTY(a))
      89       24840 :         r = copy_intArrayType(b);
      90     4442610 :     if (ARRISEMPTY(b))
      91        8232 :         r = copy_intArrayType(a);
      92             : 
      93     4442610 :     if (!r)
      94             :     {
      95     4409538 :         int         na = ARRNELEMS(a),
      96     4409538 :                     nb = ARRNELEMS(b);
      97     4409538 :         int        *da = ARRPTR(a),
      98     4409538 :                    *db = ARRPTR(b);
      99             :         int         i,
     100             :                     j,
     101             :                    *dr;
     102             : 
     103     4409538 :         r = new_intArrayType(na + nb);
     104     4409538 :         dr = ARRPTR(r);
     105             : 
     106             :         /* union */
     107     4409538 :         i = j = 0;
     108   173234828 :         while (i < na && j < nb)
     109             :         {
     110   168825290 :             if (da[i] == db[j])
     111             :             {
     112    11501828 :                 *dr++ = da[i++];
     113    11501828 :                 j++;
     114             :             }
     115   157323462 :             else if (da[i] < db[j])
     116   132661914 :                 *dr++ = da[i++];
     117             :             else
     118    24661548 :                 *dr++ = db[j++];
     119             :         }
     120             : 
     121    15628696 :         while (i < na)
     122    11219158 :             *dr++ = da[i++];
     123     8334714 :         while (j < nb)
     124     3925176 :             *dr++ = db[j++];
     125             : 
     126     4409538 :         r = resize_intArrayType(r, dr - ARRPTR(r));
     127             :     }
     128             : 
     129     4442610 :     if (ARRNELEMS(r) > 1)
     130     4442566 :         r = _int_unique(r);
     131             : 
     132     4442610 :     return r;
     133             : }
     134             : 
     135             : ArrayType *
     136     3527600 : 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     3527600 :     if (ARRISEMPTY(a) || ARRISEMPTY(b))
     149       32390 :         return new_intArrayType(0);
     150             : 
     151     3495210 :     na = ARRNELEMS(a);
     152     3495210 :     nb = ARRNELEMS(b);
     153     3495210 :     da = ARRPTR(a);
     154     3495210 :     db = ARRPTR(b);
     155     3495210 :     r = new_intArrayType(Min(na, nb));
     156     3495210 :     dr = ARRPTR(r);
     157             : 
     158     3495210 :     i = j = k = 0;
     159    45173648 :     while (i < na && j < nb)
     160             :     {
     161    41678438 :         if (da[i] < db[j])
     162    18913510 :             i++;
     163    22764928 :         else if (da[i] == db[j])
     164             :         {
     165     4036324 :             if (k == 0 || dr[k - 1] != db[j])
     166     4036324 :                 dr[k++] = db[j];
     167     4036324 :             i++;
     168     4036324 :             j++;
     169             :         }
     170             :         else
     171    18728604 :             j++;
     172             :     }
     173             : 
     174     3495210 :     if (k == 0)
     175             :     {
     176     2762964 :         pfree(r);
     177     2762964 :         return new_intArrayType(0);
     178             :     }
     179             :     else
     180      732246 :         return resize_intArrayType(r, k);
     181             : }
     182             : 
     183             : void
     184     8623396 : rt__int_size(ArrayType *a, float *size)
     185             : {
     186     8623396 :     *size = (float) ARRNELEMS(a);
     187     8623396 : }
     188             : 
     189             : /* comparison function for isort() and _int_unique() */
     190             : static inline int
     191   721299488 : isort_cmp(const void *a, const void *b, void *arg)
     192             : {
     193   721299488 :     int32       aval = *((const int32 *) a);
     194   721299488 :     int32       bval = *((const int32 *) b);
     195             : 
     196   721299488 :     if (*((bool *) arg))
     197             :     {
     198             :         /* compare for ascending order */
     199   721299476 :         if (aval < bval)
     200   313471306 :             return -1;
     201   407828170 :         if (aval > bval)
     202   405508532 :             return 1;
     203             :     }
     204             :     else
     205             :     {
     206          12 :         if (aval > bval)
     207           8 :             return -1;
     208           4 :         if (aval < bval)
     209           4 :             return 1;
     210             :     }
     211     2319638 :     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    10912132 : new_intArrayType(int num)
     225             : {
     226             :     ArrayType  *r;
     227             :     int         nbytes;
     228             : 
     229             :     /* if no elements, return a zero-dimensional array */
     230    10912132 :     if (num <= 0)
     231             :     {
     232             :         Assert(num == 0);
     233     2795764 :         r = construct_empty_array(INT4OID);
     234     2795764 :         return r;
     235             :     }
     236             : 
     237     8116368 :     nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num;
     238             : 
     239     8116368 :     r = (ArrayType *) palloc0(nbytes);
     240             : 
     241     8116368 :     SET_VARSIZE(r, nbytes);
     242     8116368 :     ARR_NDIM(r) = 1;
     243     8116368 :     r->dataoffset = 0;           /* marker for no null bitmap */
     244     8116368 :     ARR_ELEMTYPE(r) = INT4OID;
     245     8116368 :     ARR_DIMS(r)[0] = num;
     246     8116368 :     ARR_LBOUND(r)[0] = 1;
     247             : 
     248     8116368 :     return r;
     249             : }
     250             : 
     251             : ArrayType *
     252    10257092 : resize_intArrayType(ArrayType *a, int num)
     253             : {
     254             :     int         nbytes;
     255             :     int         i;
     256             : 
     257             :     /* if no elements, return a zero-dimensional array */
     258    10257092 :     if (num <= 0)
     259             :     {
     260             :         Assert(num == 0);
     261         432 :         a = construct_empty_array(INT4OID);
     262         432 :         return a;
     263             :     }
     264             : 
     265    10256660 :     if (num == ARRNELEMS(a))
     266     7921058 :         return a;
     267             : 
     268     2335602 :     nbytes = ARR_DATA_OFFSET(a) + sizeof(int) * num;
     269             : 
     270     2335602 :     a = (ArrayType *) repalloc(a, nbytes);
     271             : 
     272     2335602 :     SET_VARSIZE(a, nbytes);
     273             :     /* usually the array should be 1-D already, but just in case ... */
     274     4671204 :     for (i = 0; i < ARR_NDIM(a); i++)
     275             :     {
     276     2335602 :         ARR_DIMS(a)[i] = num;
     277     2335602 :         num = 1;
     278             :     }
     279     2335602 :     return a;
     280             : }
     281             : 
     282             : ArrayType *
     283       35824 : copy_intArrayType(ArrayType *a)
     284             : {
     285             :     ArrayType  *r;
     286       35824 :     int         n = ARRNELEMS(a);
     287             : 
     288       35824 :     r = new_intArrayType(n);
     289       35824 :     memcpy(ARRPTR(r), ARRPTR(a), n * sizeof(int32));
     290       35824 :     return r;
     291             : }
     292             : 
     293             : /* num for compressed key */
     294             : int
     295       60286 : internal_size(int *a, int len)
     296             : {
     297             :     int         i;
     298       60286 :     int64       size = 0;
     299             : 
     300    14444630 :     for (i = 0; i < len; i += 2)
     301             :     {
     302    14384344 :         if (!i || a[i] != a[i - 1]) /* do not count repeated range */
     303    14384344 :             size += (int64) (a[i + 1]) - (int64) (a[i]) + 1;
     304             :     }
     305             : 
     306       60286 :     if (size > (int64) INT_MAX || size < (int64) INT_MIN)
     307           0 :         return -1;              /* overflow */
     308       60286 :     return (int) size;
     309             : }
     310             : 
     311             : /* unique-ify elements of r in-place ... r must be sorted already */
     312             : ArrayType *
     313     5109228 : _int_unique(ArrayType *r)
     314             : {
     315     5109228 :     int         num = ARRNELEMS(r);
     316     5109228 :     bool        ascending = true;
     317             : 
     318     5109228 :     num = qunique_arg(ARRPTR(r), num, sizeof(int), isort_cmp,
     319             :                       &ascending);
     320             : 
     321     5109228 :     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           2 : intarray_match_first(ArrayType *a, int32 elem)
     339             : {
     340             :     int32      *aa,
     341             :                 c,
     342             :                 i;
     343             : 
     344           2 :     CHECKARRVALID(a);
     345           2 :     c = ARRNELEMS(a);
     346           2 :     aa = ARRPTR(a);
     347           4 :     for (i = 0; i < c; i++)
     348           4 :         if (aa[i] == elem)
     349           2 :             return (i + 1);
     350           0 :     return 0;
     351             : }
     352             : 
     353             : ArrayType *
     354           8 : intarray_add_elem(ArrayType *a, int32 elem)
     355             : {
     356             :     ArrayType  *result;
     357             :     int32      *r;
     358             :     int32       c;
     359             : 
     360           8 :     CHECKARRVALID(a);
     361           8 :     c = ARRNELEMS(a);
     362           8 :     result = new_intArrayType(c + 1);
     363           8 :     r = ARRPTR(result);
     364           8 :     if (c > 0)
     365           8 :         memcpy(r, ARRPTR(a), c * sizeof(int32));
     366           8 :     r[c] = elem;
     367           8 :     return result;
     368             : }
     369             : 
     370             : ArrayType *
     371           2 : intarray_concat_arrays(ArrayType *a, ArrayType *b)
     372             : {
     373             :     ArrayType  *result;
     374           2 :     int32       ac = ARRNELEMS(a);
     375           2 :     int32       bc = ARRNELEMS(b);
     376             : 
     377           2 :     CHECKARRVALID(a);
     378           2 :     CHECKARRVALID(b);
     379           2 :     result = new_intArrayType(ac + bc);
     380           2 :     if (ac)
     381           2 :         memcpy(ARRPTR(result), ARRPTR(a), ac * sizeof(int32));
     382           2 :     if (bc)
     383           2 :         memcpy(ARRPTR(result) + ac, ARRPTR(b), bc * sizeof(int32));
     384           2 :     return result;
     385             : }
     386             : 
     387             : ArrayType *
     388           2 : int_to_intset(int32 elem)
     389             : {
     390             :     ArrayType  *result;
     391             :     int32      *aa;
     392             : 
     393           2 :     result = new_intArrayType(1);
     394           2 :     aa = ARRPTR(result);
     395           2 :     aa[0] = elem;
     396           2 :     return result;
     397             : }

Generated by: LCOV version 1.14