Header And Logo

PostgreSQL
| The world's most advanced open source database.

_int_tool.c

Go to the documentation of this file.
00001 /*
00002  * contrib/intarray/_int_tool.c
00003  */
00004 #include "postgres.h"
00005 
00006 #include "catalog/pg_type.h"
00007 
00008 #include "_int.h"
00009 
00010 
00011 /* arguments are assumed sorted & unique-ified */
00012 bool
00013 inner_int_contains(ArrayType *a, ArrayType *b)
00014 {
00015     int         na,
00016                 nb;
00017     int         i,
00018                 j,
00019                 n;
00020     int        *da,
00021                *db;
00022 
00023     na = ARRNELEMS(a);
00024     nb = ARRNELEMS(b);
00025     da = ARRPTR(a);
00026     db = ARRPTR(b);
00027 
00028     i = j = n = 0;
00029     while (i < na && j < nb)
00030     {
00031         if (da[i] < db[j])
00032             i++;
00033         else if (da[i] == db[j])
00034         {
00035             n++;
00036             i++;
00037             j++;
00038         }
00039         else
00040             break;              /* db[j] is not in da */
00041     }
00042 
00043     return (n == nb) ? TRUE : FALSE;
00044 }
00045 
00046 /* arguments are assumed sorted */
00047 bool
00048 inner_int_overlap(ArrayType *a, ArrayType *b)
00049 {
00050     int         na,
00051                 nb;
00052     int         i,
00053                 j;
00054     int        *da,
00055                *db;
00056 
00057     na = ARRNELEMS(a);
00058     nb = ARRNELEMS(b);
00059     da = ARRPTR(a);
00060     db = ARRPTR(b);
00061 
00062     i = j = 0;
00063     while (i < na && j < nb)
00064     {
00065         if (da[i] < db[j])
00066             i++;
00067         else if (da[i] == db[j])
00068             return TRUE;
00069         else
00070             j++;
00071     }
00072 
00073     return FALSE;
00074 }
00075 
00076 ArrayType *
00077 inner_int_union(ArrayType *a, ArrayType *b)
00078 {
00079     ArrayType  *r = NULL;
00080 
00081     CHECKARRVALID(a);
00082     CHECKARRVALID(b);
00083 
00084     if (ARRISEMPTY(a) && ARRISEMPTY(b))
00085         return new_intArrayType(0);
00086     if (ARRISEMPTY(a))
00087         r = copy_intArrayType(b);
00088     if (ARRISEMPTY(b))
00089         r = copy_intArrayType(a);
00090 
00091     if (!r)
00092     {
00093         int         na = ARRNELEMS(a),
00094                     nb = ARRNELEMS(b);
00095         int        *da = ARRPTR(a),
00096                    *db = ARRPTR(b);
00097         int         i,
00098                     j,
00099                    *dr;
00100 
00101         r = new_intArrayType(na + nb);
00102         dr = ARRPTR(r);
00103 
00104         /* union */
00105         i = j = 0;
00106         while (i < na && j < nb)
00107         {
00108             if (da[i] == db[j])
00109             {
00110                 *dr++ = da[i++];
00111                 j++;
00112             }
00113             else if (da[i] < db[j])
00114                 *dr++ = da[i++];
00115             else
00116                 *dr++ = db[j++];
00117         }
00118 
00119         while (i < na)
00120             *dr++ = da[i++];
00121         while (j < nb)
00122             *dr++ = db[j++];
00123 
00124         r = resize_intArrayType(r, dr - ARRPTR(r));
00125     }
00126 
00127     if (ARRNELEMS(r) > 1)
00128         r = _int_unique(r);
00129 
00130     return r;
00131 }
00132 
00133 ArrayType *
00134 inner_int_inter(ArrayType *a, ArrayType *b)
00135 {
00136     ArrayType  *r;
00137     int         na,
00138                 nb;
00139     int        *da,
00140                *db,
00141                *dr;
00142     int         i,
00143                 j,
00144                 k;
00145 
00146     if (ARRISEMPTY(a) || ARRISEMPTY(b))
00147         return new_intArrayType(0);
00148 
00149     na = ARRNELEMS(a);
00150     nb = ARRNELEMS(b);
00151     da = ARRPTR(a);
00152     db = ARRPTR(b);
00153     r = new_intArrayType(Min(na, nb));
00154     dr = ARRPTR(r);
00155 
00156     i = j = k = 0;
00157     while (i < na && j < nb)
00158     {
00159         if (da[i] < db[j])
00160             i++;
00161         else if (da[i] == db[j])
00162         {
00163             if (k == 0 || dr[k - 1] != db[j])
00164                 dr[k++] = db[j];
00165             i++;
00166             j++;
00167         }
00168         else
00169             j++;
00170     }
00171 
00172     if (k == 0)
00173     {
00174         pfree(r);
00175         return new_intArrayType(0);
00176     }
00177     else
00178         return resize_intArrayType(r, k);
00179 }
00180 
00181 void
00182 rt__int_size(ArrayType *a, float *size)
00183 {
00184     *size = (float) ARRNELEMS(a);
00185 }
00186 
00187 /* Sort the given data (len >= 2).  Return true if any duplicates found */
00188 bool
00189 isort(int32 *a, int len)
00190 {
00191     int32       cur,
00192                 prev;
00193     int32      *pcur,
00194                *pprev,
00195                *end;
00196     bool        r = FALSE;
00197 
00198     /*
00199      * We use a simple insertion sort.  While this is O(N^2) in the worst
00200      * case, it's quite fast if the input is already sorted or nearly so.
00201      * Also, for not-too-large inputs it's faster than more complex methods
00202      * anyhow.
00203      */
00204     end = a + len;
00205     for (pcur = a + 1; pcur < end; pcur++)
00206     {
00207         cur = *pcur;
00208         for (pprev = pcur - 1; pprev >= a; pprev--)
00209         {
00210             prev = *pprev;
00211             if (prev <= cur)
00212             {
00213                 if (prev == cur)
00214                     r = TRUE;
00215                 break;
00216             }
00217             pprev[1] = prev;
00218         }
00219         pprev[1] = cur;
00220     }
00221     return r;
00222 }
00223 
00224 /* Create a new int array with room for "num" elements */
00225 ArrayType *
00226 new_intArrayType(int num)
00227 {
00228     ArrayType  *r;
00229     int         nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num;
00230 
00231     r = (ArrayType *) palloc0(nbytes);
00232 
00233     SET_VARSIZE(r, nbytes);
00234     ARR_NDIM(r) = 1;
00235     r->dataoffset = 0;          /* marker for no null bitmap */
00236     ARR_ELEMTYPE(r) = INT4OID;
00237     ARR_DIMS(r)[0] = num;
00238     ARR_LBOUND(r)[0] = 1;
00239 
00240     return r;
00241 }
00242 
00243 ArrayType *
00244 resize_intArrayType(ArrayType *a, int num)
00245 {
00246     int         nbytes = ARR_DATA_OFFSET(a) + sizeof(int) * num;
00247     int         i;
00248 
00249     if (num == ARRNELEMS(a))
00250         return a;
00251 
00252     a = (ArrayType *) repalloc(a, nbytes);
00253 
00254     SET_VARSIZE(a, nbytes);
00255     /* usually the array should be 1-D already, but just in case ... */
00256     for (i = 0; i < ARR_NDIM(a); i++)
00257     {
00258         ARR_DIMS(a)[i] = num;
00259         num = 1;
00260     }
00261     return a;
00262 }
00263 
00264 ArrayType *
00265 copy_intArrayType(ArrayType *a)
00266 {
00267     ArrayType  *r;
00268     int         n = ARRNELEMS(a);
00269 
00270     r = new_intArrayType(n);
00271     memcpy(ARRPTR(r), ARRPTR(a), n * sizeof(int32));
00272     return r;
00273 }
00274 
00275 /* num for compressed key */
00276 int
00277 internal_size(int *a, int len)
00278 {
00279     int         i,
00280                 size = 0;
00281 
00282     for (i = 0; i < len; i += 2)
00283     {
00284         if (!i || a[i] != a[i - 1])     /* do not count repeated range */
00285             size += a[i + 1] - a[i] + 1;
00286     }
00287 
00288     return size;
00289 }
00290 
00291 /* unique-ify elements of r in-place ... r must be sorted already */
00292 ArrayType *
00293 _int_unique(ArrayType *r)
00294 {
00295     int        *tmp,
00296                *dr,
00297                *data;
00298     int         num = ARRNELEMS(r);
00299 
00300     if (num < 2)
00301         return r;
00302 
00303     data = tmp = dr = ARRPTR(r);
00304     while (tmp - data < num)
00305     {
00306         if (*tmp != *dr)
00307             *(++dr) = *tmp++;
00308         else
00309             tmp++;
00310     }
00311     return resize_intArrayType(r, dr + 1 - ARRPTR(r));
00312 }
00313 
00314 void
00315 gensign(BITVEC sign, int *a, int len)
00316 {
00317     int         i;
00318 
00319     /* we assume that the sign vector is previously zeroed */
00320     for (i = 0; i < len; i++)
00321     {
00322         HASH(sign, *a);
00323         a++;
00324     }
00325 }
00326 
00327 int32
00328 intarray_match_first(ArrayType *a, int32 elem)
00329 {
00330     int32      *aa,
00331                 c,
00332                 i;
00333 
00334     CHECKARRVALID(a);
00335     c = ARRNELEMS(a);
00336     aa = ARRPTR(a);
00337     for (i = 0; i < c; i++)
00338         if (aa[i] == elem)
00339             return (i + 1);
00340     return 0;
00341 }
00342 
00343 ArrayType *
00344 intarray_add_elem(ArrayType *a, int32 elem)
00345 {
00346     ArrayType  *result;
00347     int32      *r;
00348     int32       c;
00349 
00350     CHECKARRVALID(a);
00351     c = ARRNELEMS(a);
00352     result = new_intArrayType(c + 1);
00353     r = ARRPTR(result);
00354     if (c > 0)
00355         memcpy(r, ARRPTR(a), c * sizeof(int32));
00356     r[c] = elem;
00357     return result;
00358 }
00359 
00360 ArrayType *
00361 intarray_concat_arrays(ArrayType *a, ArrayType *b)
00362 {
00363     ArrayType  *result;
00364     int32       ac = ARRNELEMS(a);
00365     int32       bc = ARRNELEMS(b);
00366 
00367     CHECKARRVALID(a);
00368     CHECKARRVALID(b);
00369     result = new_intArrayType(ac + bc);
00370     if (ac)
00371         memcpy(ARRPTR(result), ARRPTR(a), ac * sizeof(int32));
00372     if (bc)
00373         memcpy(ARRPTR(result) + ac, ARRPTR(b), bc * sizeof(int32));
00374     return result;
00375 }
00376 
00377 ArrayType *
00378 int_to_intset(int32 n)
00379 {
00380     ArrayType  *result;
00381     int32      *aa;
00382 
00383     result = new_intArrayType(1);
00384     aa = ARRPTR(result);
00385     aa[0] = n;
00386     return result;
00387 }
00388 
00389 int
00390 compASC(const void *a, const void *b)
00391 {
00392     if (*(const int32 *) a == *(const int32 *) b)
00393         return 0;
00394     return (*(const int32 *) a > *(const int32 *) b) ? 1 : -1;
00395 }
00396 
00397 int
00398 compDESC(const void *a, const void *b)
00399 {
00400     if (*(const int32 *) a == *(const int32 *) b)
00401         return 0;
00402     return (*(const int32 *) a < *(const int32 *) b) ? 1 : -1;
00403 }