2 * contrib/intarray/_int_tool.c
9 #include "catalog/pg_type.h"
10 #include "lib/qunique.h"
12 /* arguments are assumed sorted & unique-ified */
14 inner_int_contains(ArrayType
*a
, ArrayType
*b
)
30 while (i
< na
&& j
< nb
)
34 else if (da
[i
] == db
[j
])
41 break; /* db[j] is not in da */
47 /* arguments are assumed sorted */
49 inner_int_overlap(ArrayType
*a
, ArrayType
*b
)
64 while (i
< na
&& j
< nb
)
68 else if (da
[i
] == db
[j
])
78 inner_int_union(ArrayType
*a
, ArrayType
*b
)
85 if (ARRISEMPTY(a
) && ARRISEMPTY(b
))
86 return new_intArrayType(0);
88 r
= copy_intArrayType(b
);
90 r
= copy_intArrayType(a
);
94 int na
= ARRNELEMS(a
),
102 r
= new_intArrayType(na
+ nb
);
107 while (i
< na
&& j
< nb
)
114 else if (da
[i
] < db
[j
])
125 r
= resize_intArrayType(r
, dr
- ARRPTR(r
));
128 if (ARRNELEMS(r
) > 1)
135 inner_int_inter(ArrayType
*a
, ArrayType
*b
)
147 if (ARRISEMPTY(a
) || ARRISEMPTY(b
))
148 return new_intArrayType(0);
154 r
= new_intArrayType(Min(na
, nb
));
158 while (i
< na
&& j
< nb
)
162 else if (da
[i
] == db
[j
])
164 if (k
== 0 || dr
[k
- 1] != db
[j
])
176 return new_intArrayType(0);
179 return resize_intArrayType(r
, k
);
183 rt__int_size(ArrayType
*a
, float *size
)
185 *size
= (float) ARRNELEMS(a
);
188 /* qsort_arg comparison function for isort() */
190 isort_cmp(const void *a
, const void *b
, void *arg
)
192 int32 aval
= *((const int32
*) a
);
193 int32 bval
= *((const int32
*) b
);
201 * Report if we have any duplicates. If there are equal keys, qsort must
202 * compare them at some point, else it wouldn't know whether one should go
203 * before or after the other.
205 *((bool *) arg
) = true;
209 /* Sort the given data (len >= 2). Return true if any duplicates found */
211 isort(int32
*a
, int len
)
215 qsort_arg(a
, len
, sizeof(int32
), isort_cmp
, (void *) &r
);
219 /* Create a new int array with room for "num" elements */
221 new_intArrayType(int num
)
226 /* if no elements, return a zero-dimensional array */
230 r
= construct_empty_array(INT4OID
);
234 nbytes
= ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num
;
236 r
= (ArrayType
*) palloc0(nbytes
);
238 SET_VARSIZE(r
, nbytes
);
240 r
->dataoffset
= 0; /* marker for no null bitmap */
241 ARR_ELEMTYPE(r
) = INT4OID
;
242 ARR_DIMS(r
)[0] = num
;
243 ARR_LBOUND(r
)[0] = 1;
249 resize_intArrayType(ArrayType
*a
, int num
)
254 /* if no elements, return a zero-dimensional array */
258 a
= construct_empty_array(INT4OID
);
262 if (num
== ARRNELEMS(a
))
265 nbytes
= ARR_DATA_OFFSET(a
) + sizeof(int) * num
;
267 a
= (ArrayType
*) repalloc(a
, nbytes
);
269 SET_VARSIZE(a
, nbytes
);
270 /* usually the array should be 1-D already, but just in case ... */
271 for (i
= 0; i
< ARR_NDIM(a
); i
++)
273 ARR_DIMS(a
)[i
] = num
;
280 copy_intArrayType(ArrayType
*a
)
283 int n
= ARRNELEMS(a
);
285 r
= new_intArrayType(n
);
286 memcpy(ARRPTR(r
), ARRPTR(a
), n
* sizeof(int32
));
290 /* num for compressed key */
292 internal_size(int *a
, int len
)
297 for (i
= 0; i
< len
; i
+= 2)
299 if (!i
|| a
[i
] != a
[i
- 1]) /* do not count repeated range */
300 size
+= (int64
) (a
[i
+ 1]) - (int64
) (a
[i
]) + 1;
303 if (size
> (int64
) INT_MAX
|| size
< (int64
) INT_MIN
)
304 return -1; /* overflow */
308 /* unique-ify elements of r in-place ... r must be sorted already */
310 _int_unique(ArrayType
*r
)
312 int num
= ARRNELEMS(r
);
313 bool duplicates_found
; /* not used */
315 num
= qunique_arg(ARRPTR(r
), num
, sizeof(int), isort_cmp
,
318 return resize_intArrayType(r
, num
);
322 gensign(BITVECP sign
, int *a
, int len
, int siglen
)
326 /* we assume that the sign vector is previously zeroed */
327 for (i
= 0; i
< len
; i
++)
329 HASH(sign
, *a
, siglen
);
335 intarray_match_first(ArrayType
*a
, int32 elem
)
344 for (i
= 0; i
< c
; i
++)
351 intarray_add_elem(ArrayType
*a
, int32 elem
)
359 result
= new_intArrayType(c
+ 1);
362 memcpy(r
, ARRPTR(a
), c
* sizeof(int32
));
368 intarray_concat_arrays(ArrayType
*a
, ArrayType
*b
)
371 int32 ac
= ARRNELEMS(a
);
372 int32 bc
= ARRNELEMS(b
);
376 result
= new_intArrayType(ac
+ bc
);
378 memcpy(ARRPTR(result
), ARRPTR(a
), ac
* sizeof(int32
));
380 memcpy(ARRPTR(result
) + ac
, ARRPTR(b
), bc
* sizeof(int32
));
385 int_to_intset(int32 n
)
390 result
= new_intArrayType(1);
397 compASC(const void *a
, const void *b
)
399 if (*(const int32
*) a
== *(const int32
*) b
)
401 return (*(const int32
*) a
> *(const int32
*) b
) ? 1 : -1;
405 compDESC(const void *a
, const void *b
)
407 if (*(const int32
*) a
== *(const int32
*) b
)
409 return (*(const int32
*) a
< *(const int32
*) b
) ? 1 : -1;