LCOV - code coverage report
Current view: top level - contrib/intarray - _int_tool.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 96.2 % 182 175
Test Date: 2026-07-03 19:57:34 Functions: 93.8 % 16 15
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 64.4 % 180 116

             Branch data     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                 :       96096 : 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                 :       96096 :     na = ARRNELEMS(a);
      26                 :       96096 :     nb = ARRNELEMS(b);
      27         [ -  + ]:       96096 :     da = ARRPTR(a);
      28         [ -  + ]:       96096 :     db = ARRPTR(b);
      29                 :             : 
      30                 :       96096 :     i = j = n = 0;
      31   [ +  +  +  + ]:      235512 :     while (i < na && j < nb)
      32                 :             :     {
      33         [ +  + ]:      228738 :         if (da[i] < db[j])
      34                 :      132811 :             i++;
      35         [ +  + ]:       95927 :         else if (da[i] == db[j])
      36                 :             :         {
      37                 :        6605 :             n++;
      38                 :        6605 :             i++;
      39                 :        6605 :             j++;
      40                 :             :         }
      41                 :             :         else
      42                 :       89322 :             break;              /* db[j] is not in da */
      43                 :             :     }
      44                 :             : 
      45                 :       96096 :     return (n == nb);
      46                 :             : }
      47                 :             : 
      48                 :             : /* arguments are assumed sorted */
      49                 :             : bool
      50                 :       24512 : 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                 :       24512 :     na = ARRNELEMS(a);
      60                 :       24512 :     nb = ARRNELEMS(b);
      61         [ -  + ]:       24512 :     da = ARRPTR(a);
      62         [ -  + ]:       24512 :     db = ARRPTR(b);
      63                 :             : 
      64                 :       24512 :     i = j = 0;
      65   [ +  +  +  + ]:      114899 :     while (i < na && j < nb)
      66                 :             :     {
      67         [ +  + ]:       93291 :         if (da[i] < db[j])
      68                 :       47119 :             i++;
      69         [ +  + ]:       46172 :         else if (da[i] == db[j])
      70                 :        2904 :             return true;
      71                 :             :         else
      72                 :       43268 :             j++;
      73                 :             :     }
      74                 :             : 
      75                 :       21608 :     return false;
      76                 :             : }
      77                 :             : 
      78                 :             : ArrayType *
      79                 :     2250951 : inner_int_union(ArrayType *a, ArrayType *b)
      80                 :             : {
      81                 :     2250951 :     ArrayType  *r = NULL;
      82                 :             : 
      83   [ -  +  -  -  :     2250951 :     CHECKARRVALID(a);
                   -  - ]
      84   [ -  +  -  -  :     2250951 :     CHECKARRVALID(b);
                   -  - ]
      85                 :             : 
      86   [ +  +  +  + ]:     2250951 :     if (ARRISEMPTY(a) && ARRISEMPTY(b))
      87                 :         177 :         return new_intArrayType(0);
      88         [ +  + ]:     2250774 :     if (ARRISEMPTY(a))
      89                 :       13800 :         r = copy_intArrayType(b);
      90         [ +  + ]:     2250774 :     if (ARRISEMPTY(b))
      91                 :        4420 :         r = copy_intArrayType(a);
      92                 :             : 
      93         [ +  + ]:     2250774 :     if (!r)
      94                 :             :     {
      95                 :     2232554 :         int         na = ARRNELEMS(a),
      96                 :     2232554 :                     nb = ARRNELEMS(b);
      97         [ -  + ]:     2232554 :         int        *da = ARRPTR(a),
      98         [ -  + ]:     2232554 :                    *db = ARRPTR(b);
      99                 :             :         int         i,
     100                 :             :                     j,
     101                 :             :                    *dr;
     102                 :             : 
     103                 :     2232554 :         r = new_intArrayType(na + nb);
     104         [ -  + ]:     2232554 :         dr = ARRPTR(r);
     105                 :             : 
     106                 :             :         /* union */
     107                 :     2232554 :         i = j = 0;
     108   [ +  +  +  + ]:    79114135 :         while (i < na && j < nb)
     109                 :             :         {
     110         [ +  + ]:    76881581 :             if (da[i] == db[j])
     111                 :             :             {
     112                 :     4715788 :                 *dr++ = da[i++];
     113                 :     4715788 :                 j++;
     114                 :             :             }
     115         [ +  + ]:    72165793 :             else if (da[i] < db[j])
     116                 :    60725925 :                 *dr++ = da[i++];
     117                 :             :             else
     118                 :    11439868 :                 *dr++ = db[j++];
     119                 :             :         }
     120                 :             : 
     121         [ +  + ]:     7621535 :         while (i < na)
     122                 :     5388981 :             *dr++ = da[i++];
     123         [ +  + ]:     4275918 :         while (j < nb)
     124                 :     2043364 :             *dr++ = db[j++];
     125                 :             : 
     126         [ -  + ]:     2232554 :         r = resize_intArrayType(r, dr - ARRPTR(r));
     127                 :             :     }
     128                 :             : 
     129         [ +  + ]:     2250774 :     if (ARRNELEMS(r) > 1)
     130                 :     2250751 :         r = _int_unique(r);
     131                 :             : 
     132                 :     2250774 :     return r;
     133                 :             : }
     134                 :             : 
     135                 :             : ArrayType *
     136                 :     1818291 : 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   [ +  +  +  + ]:     1818291 :     if (ARRISEMPTY(a) || ARRISEMPTY(b))
     149                 :       17793 :         return new_intArrayType(0);
     150                 :             : 
     151                 :     1800498 :     na = ARRNELEMS(a);
     152                 :     1800498 :     nb = ARRNELEMS(b);
     153         [ -  + ]:     1800498 :     da = ARRPTR(a);
     154         [ -  + ]:     1800498 :     db = ARRPTR(b);
     155                 :     1800498 :     r = new_intArrayType(Min(na, nb));
     156         [ -  + ]:     1800498 :     dr = ARRPTR(r);
     157                 :             : 
     158                 :     1800498 :     i = j = k = 0;
     159   [ +  +  +  + ]:    21726418 :     while (i < na && j < nb)
     160                 :             :     {
     161         [ +  + ]:    19925920 :         if (da[i] < db[j])
     162                 :     9272798 :             i++;
     163         [ +  + ]:    10653122 :         else if (da[i] == db[j])
     164                 :             :         {
     165   [ +  +  +  - ]:     1633679 :             if (k == 0 || dr[k - 1] != db[j])
     166                 :     1633679 :                 dr[k++] = db[j];
     167                 :     1633679 :             i++;
     168                 :     1633679 :             j++;
     169                 :             :         }
     170                 :             :         else
     171                 :     9019443 :             j++;
     172                 :             :     }
     173                 :             : 
     174         [ +  + ]:     1800498 :     if (k == 0)
     175                 :             :     {
     176                 :     1429735 :         pfree(r);
     177                 :     1429735 :         return new_intArrayType(0);
     178                 :             :     }
     179                 :             :     else
     180                 :      370763 :         return resize_intArrayType(r, k);
     181                 :             : }
     182                 :             : 
     183                 :             : void
     184                 :     4371222 : rt__int_size(ArrayType *a, float *size)
     185                 :             : {
     186                 :     4371222 :     *size = (float) ARRNELEMS(a);
     187                 :     4371222 : }
     188                 :             : 
     189                 :             : /* comparison function for isort() and _int_unique() */
     190                 :             : static inline int
     191                 :   320479778 : isort_cmp(const void *a, const void *b, void *arg)
     192                 :             : {
     193                 :   320479778 :     int32       aval = *((const int32 *) a);
     194                 :   320479778 :     int32       bval = *((const int32 *) b);
     195                 :             : 
     196         [ +  + ]:   320479778 :     if (*((bool *) arg))
     197                 :             :     {
     198                 :             :         /* compare for ascending order */
     199         [ +  + ]:   320479772 :         if (aval < bval)
     200                 :   137481863 :             return -1;
     201         [ +  + ]:   182997909 :         if (aval > bval)
     202                 :   181933236 :             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                 :     1064673 :     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                 :     5581287 : new_intArrayType(int num)
     225                 :             : {
     226                 :             :     ArrayType  *r;
     227                 :             :     int         nbytes;
     228                 :             : 
     229                 :             :     /* if no elements, return a zero-dimensional array */
     230         [ +  + ]:     5581287 :     if (num <= 0)
     231                 :             :     {
     232                 :             :         Assert(num == 0);
     233                 :     1447705 :         r = construct_empty_array(INT4OID);
     234                 :     1447705 :         return r;
     235                 :             :     }
     236                 :             : 
     237                 :     4133582 :     nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num;
     238                 :             : 
     239                 :     4133582 :     r = (ArrayType *) palloc0(nbytes);
     240                 :             : 
     241                 :     4133582 :     SET_VARSIZE(r, nbytes);
     242                 :     4133582 :     ARR_NDIM(r) = 1;
     243                 :     4133582 :     r->dataoffset = 0;           /* marker for no null bitmap */
     244                 :     4133582 :     ARR_ELEMTYPE(r) = INT4OID;
     245                 :     4133582 :     ARR_DIMS(r)[0] = num;
     246                 :     4133582 :     ARR_LBOUND(r)[0] = 1;
     247                 :             : 
     248                 :     4133582 :     return r;
     249                 :             : }
     250                 :             : 
     251                 :             : ArrayType *
     252                 :     5200296 : resize_intArrayType(ArrayType *a, int num)
     253                 :             : {
     254                 :             :     int         nbytes;
     255                 :             :     int         i;
     256                 :             : 
     257                 :             :     /* if no elements, return a zero-dimensional array */
     258         [ +  + ]:     5200296 :     if (num <= 0)
     259                 :             :     {
     260                 :             :         Assert(num == 0);
     261                 :         234 :         a = construct_empty_array(INT4OID);
     262                 :         234 :         return a;
     263                 :             :     }
     264                 :             : 
     265         [ +  + ]:     5200062 :     if (num == ARRNELEMS(a))
     266                 :     4047983 :         return a;
     267                 :             : 
     268         [ -  + ]:     1152079 :     nbytes = ARR_DATA_OFFSET(a) + sizeof(int) * num;
     269                 :             : 
     270                 :     1152079 :     a = (ArrayType *) repalloc(a, nbytes);
     271                 :             : 
     272                 :     1152079 :     SET_VARSIZE(a, nbytes);
     273                 :             :     /* usually the array should be 1-D already, but just in case ... */
     274         [ +  + ]:     2304158 :     for (i = 0; i < ARR_NDIM(a); i++)
     275                 :             :     {
     276                 :     1152079 :         ARR_DIMS(a)[i] = num;
     277                 :     1152079 :         num = 1;
     278                 :             :     }
     279                 :     1152079 :     return a;
     280                 :             : }
     281                 :             : 
     282                 :             : ArrayType *
     283                 :       19362 : copy_intArrayType(ArrayType *a)
     284                 :             : {
     285                 :             :     ArrayType  *r;
     286                 :       19362 :     int         n = ARRNELEMS(a);
     287                 :             : 
     288                 :       19362 :     r = new_intArrayType(n);
     289   [ -  +  -  + ]:       19362 :     memcpy(ARRPTR(r), ARRPTR(a), n * sizeof(int32));
     290                 :       19362 :     return r;
     291                 :             : }
     292                 :             : 
     293                 :             : /* num for compressed key */
     294                 :             : int
     295                 :       26779 : internal_size(int *a, int len)
     296                 :             : {
     297                 :             :     int         i;
     298                 :       26779 :     int64       size = 0;
     299                 :             : 
     300         [ +  + ]:     6434455 :     for (i = 0; i < len; i += 2)
     301                 :             :     {
     302   [ +  +  +  - ]:     6407676 :         if (!i || a[i] != a[i - 1]) /* do not count repeated range */
     303                 :     6407676 :             size += (int64) (a[i + 1]) - (int64) (a[i]) + 1;
     304                 :             :     }
     305                 :             : 
     306   [ +  -  -  + ]:       26779 :     if (size > (int64) INT_MAX || size < (int64) INT_MIN)
     307                 :           0 :         return -1;              /* overflow */
     308                 :       26779 :     return (int) size;
     309                 :             : }
     310                 :             : 
     311                 :             : /* unique-ify elements of r in-place ... r must be sorted already */
     312                 :             : ArrayType *
     313                 :     2594341 : _int_unique(ArrayType *r)
     314                 :             : {
     315                 :     2594341 :     int         num = ARRNELEMS(r);
     316                 :     2594341 :     bool        ascending = true;
     317                 :             : 
     318         [ -  + ]:     2594341 :     num = qunique_arg(ARRPTR(r), num, sizeof(int), isort_cmp,
     319                 :             :                       &ascending);
     320                 :             : 
     321                 :     2594341 :     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