LCOV - code coverage report
Current view: top level - contrib/intarray - _int_tool.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 176 185 95.1 %
Date: 2024-11-21 10:14:43 Functions: 18 19 94.7 %
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      190114 : 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      190114 :     na = ARRNELEMS(a);
      26      190114 :     nb = ARRNELEMS(b);
      27      190114 :     da = ARRPTR(a);
      28      190114 :     db = ARRPTR(b);
      29             : 
      30      190114 :     i = j = n = 0;
      31      465768 :     while (i < na && j < nb)
      32             :     {
      33      452068 :         if (da[i] < db[j])
      34      262486 :             i++;
      35      189582 :         else if (da[i] == db[j])
      36             :         {
      37       13168 :             n++;
      38       13168 :             i++;
      39       13168 :             j++;
      40             :         }
      41             :         else
      42      176414 :             break;              /* db[j] is not in da */
      43             :     }
      44             : 
      45      190114 :     return (n == nb);
      46             : }
      47             : 
      48             : /* arguments are assumed sorted */
      49             : bool
      50       48360 : 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       48360 :     na = ARRNELEMS(a);
      60       48360 :     nb = ARRNELEMS(b);
      61       48360 :     da = ARRPTR(a);
      62       48360 :     db = ARRPTR(b);
      63             : 
      64       48360 :     i = j = 0;
      65      224514 :     while (i < na && j < nb)
      66             :     {
      67      181894 :         if (da[i] < db[j])
      68       90972 :             i++;
      69       90922 :         else if (da[i] == db[j])
      70        5740 :             return true;
      71             :         else
      72       85182 :             j++;
      73             :     }
      74             : 
      75       42620 :     return false;
      76             : }
      77             : 
      78             : ArrayType *
      79     4481094 : inner_int_union(ArrayType *a, ArrayType *b)
      80             : {
      81     4481094 :     ArrayType  *r = NULL;
      82             : 
      83     4481094 :     CHECKARRVALID(a);
      84     4481094 :     CHECKARRVALID(b);
      85             : 
      86     4481094 :     if (ARRISEMPTY(a) && ARRISEMPTY(b))
      87         322 :         return new_intArrayType(0);
      88     4480772 :     if (ARRISEMPTY(a))
      89       24840 :         r = copy_intArrayType(b);
      90     4480772 :     if (ARRISEMPTY(b))
      91        8248 :         r = copy_intArrayType(a);
      92             : 
      93     4480772 :     if (!r)
      94             :     {
      95     4447684 :         int         na = ARRNELEMS(a),
      96     4447684 :                     nb = ARRNELEMS(b);
      97     4447684 :         int        *da = ARRPTR(a),
      98     4447684 :                    *db = ARRPTR(b);
      99             :         int         i,
     100             :                     j,
     101             :                    *dr;
     102             : 
     103     4447684 :         r = new_intArrayType(na + nb);
     104     4447684 :         dr = ARRPTR(r);
     105             : 
     106             :         /* union */
     107     4447684 :         i = j = 0;
     108   161443264 :         while (i < na && j < nb)
     109             :         {
     110   156995580 :             if (da[i] == db[j])
     111             :             {
     112     9613930 :                 *dr++ = da[i++];
     113     9613930 :                 j++;
     114             :             }
     115   147381650 :             else if (da[i] < db[j])
     116   124036890 :                 *dr++ = da[i++];
     117             :             else
     118    23344760 :                 *dr++ = db[j++];
     119             :         }
     120             : 
     121    15430380 :         while (i < na)
     122    10982696 :             *dr++ = da[i++];
     123     8497026 :         while (j < nb)
     124     4049342 :             *dr++ = db[j++];
     125             : 
     126     4447684 :         r = resize_intArrayType(r, dr - ARRPTR(r));
     127             :     }
     128             : 
     129     4480772 :     if (ARRNELEMS(r) > 1)
     130     4480738 :         r = _int_unique(r);
     131             : 
     132     4480772 :     return r;
     133             : }
     134             : 
     135             : ArrayType *
     136     3595440 : 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     3595440 :     if (ARRISEMPTY(a) || ARRISEMPTY(b))
     149       32294 :         return new_intArrayType(0);
     150             : 
     151     3563146 :     na = ARRNELEMS(a);
     152     3563146 :     nb = ARRNELEMS(b);
     153     3563146 :     da = ARRPTR(a);
     154     3563146 :     db = ARRPTR(b);
     155     3563146 :     r = new_intArrayType(Min(na, nb));
     156     3563146 :     dr = ARRPTR(r);
     157             : 
     158     3563146 :     i = j = k = 0;
     159    44209740 :     while (i < na && j < nb)
     160             :     {
     161    40646594 :         if (da[i] < db[j])
     162    18851184 :             i++;
     163    21795410 :         else if (da[i] == db[j])
     164             :         {
     165     3417448 :             if (k == 0 || dr[k - 1] != db[j])
     166     3417448 :                 dr[k++] = db[j];
     167     3417448 :             i++;
     168     3417448 :             j++;
     169             :         }
     170             :         else
     171    18377962 :             j++;
     172             :     }
     173             : 
     174     3563146 :     if (k == 0)
     175             :     {
     176     2820596 :         pfree(r);
     177     2820596 :         return new_intArrayType(0);
     178             :     }
     179             :     else
     180      742550 :         return resize_intArrayType(r, k);
     181             : }
     182             : 
     183             : void
     184     8700568 : rt__int_size(ArrayType *a, float *size)
     185             : {
     186     8700568 :     *size = (float) ARRNELEMS(a);
     187     8700568 : }
     188             : 
     189             : /* qsort_arg comparison function for isort() */
     190             : static int
     191   202933130 : isort_cmp(const void *a, const void *b, void *arg)
     192             : {
     193   202933130 :     int32       aval = *((const int32 *) a);
     194   202933130 :     int32       bval = *((const int32 *) b);
     195             : 
     196   202933130 :     if (aval < bval)
     197     1246996 :         return -1;
     198   201686134 :     if (aval > bval)
     199   200669116 :         return 1;
     200             : 
     201             :     /*
     202             :      * Report if we have any duplicates.  If there are equal keys, qsort must
     203             :      * compare them at some point, else it wouldn't know whether one should go
     204             :      * before or after the other.
     205             :      */
     206     1017018 :     *((bool *) arg) = true;
     207     1017018 :     return 0;
     208             : }
     209             : 
     210             : /* Sort the given data (len >= 2).  Return true if any duplicates found */
     211             : bool
     212      574534 : isort(int32 *a, int len)
     213             : {
     214      574534 :     bool        r = false;
     215             : 
     216      574534 :     qsort_arg(a, len, sizeof(int32), isort_cmp, &r);
     217      574534 :     return r;
     218             : }
     219             : 
     220             : /* Create a new int array with room for "num" elements */
     221             : ArrayType *
     222    11061976 : new_intArrayType(int num)
     223             : {
     224             :     ArrayType  *r;
     225             :     int         nbytes;
     226             : 
     227             :     /* if no elements, return a zero-dimensional array */
     228    11061976 :     if (num <= 0)
     229             :     {
     230             :         Assert(num == 0);
     231     2853212 :         r = construct_empty_array(INT4OID);
     232     2853212 :         return r;
     233             :     }
     234             : 
     235     8208764 :     nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num;
     236             : 
     237     8208764 :     r = (ArrayType *) palloc0(nbytes);
     238             : 
     239     8208764 :     SET_VARSIZE(r, nbytes);
     240     8208764 :     ARR_NDIM(r) = 1;
     241     8208764 :     r->dataoffset = 0;           /* marker for no null bitmap */
     242     8208764 :     ARR_ELEMTYPE(r) = INT4OID;
     243     8208764 :     ARR_DIMS(r)[0] = num;
     244     8208764 :     ARR_LBOUND(r)[0] = 1;
     245             : 
     246     8208764 :     return r;
     247             : }
     248             : 
     249             : ArrayType *
     250     9806272 : resize_intArrayType(ArrayType *a, int num)
     251             : {
     252             :     int         nbytes;
     253             :     int         i;
     254             : 
     255             :     /* if no elements, return a zero-dimensional array */
     256     9806272 :     if (num <= 0)
     257             :     {
     258             :         Assert(num == 0);
     259           0 :         a = construct_empty_array(INT4OID);
     260           0 :         return a;
     261             :     }
     262             : 
     263     9806272 :     if (num == ARRNELEMS(a))
     264     7479452 :         return a;
     265             : 
     266     2326820 :     nbytes = ARR_DATA_OFFSET(a) + sizeof(int) * num;
     267             : 
     268     2326820 :     a = (ArrayType *) repalloc(a, nbytes);
     269             : 
     270     2326820 :     SET_VARSIZE(a, nbytes);
     271             :     /* usually the array should be 1-D already, but just in case ... */
     272     4653640 :     for (i = 0; i < ARR_NDIM(a); i++)
     273             :     {
     274     2326820 :         ARR_DIMS(a)[i] = num;
     275     2326820 :         num = 1;
     276             :     }
     277     2326820 :     return a;
     278             : }
     279             : 
     280             : ArrayType *
     281       35384 : copy_intArrayType(ArrayType *a)
     282             : {
     283             :     ArrayType  *r;
     284       35384 :     int         n = ARRNELEMS(a);
     285             : 
     286       35384 :     r = new_intArrayType(n);
     287       35384 :     memcpy(ARRPTR(r), ARRPTR(a), n * sizeof(int32));
     288       35384 :     return r;
     289             : }
     290             : 
     291             : /* num for compressed key */
     292             : int
     293       52706 : internal_size(int *a, int len)
     294             : {
     295             :     int         i;
     296       52706 :     int64       size = 0;
     297             : 
     298    12520810 :     for (i = 0; i < len; i += 2)
     299             :     {
     300    12468104 :         if (!i || a[i] != a[i - 1]) /* do not count repeated range */
     301    12468104 :             size += (int64) (a[i + 1]) - (int64) (a[i]) + 1;
     302             :     }
     303             : 
     304       52706 :     if (size > (int64) INT_MAX || size < (int64) INT_MIN)
     305           0 :         return -1;              /* overflow */
     306       52706 :     return (int) size;
     307             : }
     308             : 
     309             : /* unique-ify elements of r in-place ... r must be sorted already */
     310             : ArrayType *
     311     4610546 : _int_unique(ArrayType *r)
     312             : {
     313     4610546 :     int         num = ARRNELEMS(r);
     314             :     bool        duplicates_found;   /* not used */
     315             : 
     316     4610546 :     num = qunique_arg(ARRPTR(r), num, sizeof(int), isort_cmp,
     317             :                       &duplicates_found);
     318             : 
     319     4610546 :     return resize_intArrayType(r, num);
     320             : }
     321             : 
     322             : void
     323           0 : gensign(BITVECP sign, int *a, int len, int siglen)
     324             : {
     325             :     int         i;
     326             : 
     327             :     /* we assume that the sign vector is previously zeroed */
     328           0 :     for (i = 0; i < len; i++)
     329             :     {
     330           0 :         HASH(sign, *a, siglen);
     331           0 :         a++;
     332             :     }
     333           0 : }
     334             : 
     335             : int32
     336           2 : intarray_match_first(ArrayType *a, int32 elem)
     337             : {
     338             :     int32      *aa,
     339             :                 c,
     340             :                 i;
     341             : 
     342           2 :     CHECKARRVALID(a);
     343           2 :     c = ARRNELEMS(a);
     344           2 :     aa = ARRPTR(a);
     345           4 :     for (i = 0; i < c; i++)
     346           4 :         if (aa[i] == elem)
     347           2 :             return (i + 1);
     348           0 :     return 0;
     349             : }
     350             : 
     351             : ArrayType *
     352           8 : intarray_add_elem(ArrayType *a, int32 elem)
     353             : {
     354             :     ArrayType  *result;
     355             :     int32      *r;
     356             :     int32       c;
     357             : 
     358           8 :     CHECKARRVALID(a);
     359           8 :     c = ARRNELEMS(a);
     360           8 :     result = new_intArrayType(c + 1);
     361           8 :     r = ARRPTR(result);
     362           8 :     if (c > 0)
     363           8 :         memcpy(r, ARRPTR(a), c * sizeof(int32));
     364           8 :     r[c] = elem;
     365           8 :     return result;
     366             : }
     367             : 
     368             : ArrayType *
     369           2 : intarray_concat_arrays(ArrayType *a, ArrayType *b)
     370             : {
     371             :     ArrayType  *result;
     372           2 :     int32       ac = ARRNELEMS(a);
     373           2 :     int32       bc = ARRNELEMS(b);
     374             : 
     375           2 :     CHECKARRVALID(a);
     376           2 :     CHECKARRVALID(b);
     377           2 :     result = new_intArrayType(ac + bc);
     378           2 :     if (ac)
     379           2 :         memcpy(ARRPTR(result), ARRPTR(a), ac * sizeof(int32));
     380           2 :     if (bc)
     381           2 :         memcpy(ARRPTR(result) + ac, ARRPTR(b), bc * sizeof(int32));
     382           2 :     return result;
     383             : }
     384             : 
     385             : ArrayType *
     386           2 : int_to_intset(int32 elem)
     387             : {
     388             :     ArrayType  *result;
     389             :     int32      *aa;
     390             : 
     391           2 :     result = new_intArrayType(1);
     392           2 :     aa = ARRPTR(result);
     393           2 :     aa[0] = elem;
     394           2 :     return result;
     395             : }
     396             : 
     397             : int
     398   437268312 : compASC(const void *a, const void *b)
     399             : {
     400   437268312 :     return pg_cmp_s32(*(const int32 *) a, *(const int32 *) b);
     401             : }
     402             : 
     403             : int
     404          12 : compDESC(const void *a, const void *b)
     405             : {
     406          12 :     return pg_cmp_s32(*(const int32 *) b, *(const int32 *) a);
     407             : }

Generated by: LCOV version 1.14