From 68db077a6970c15d7b13dcb239f6249d72084513 Mon Sep 17 00:00:00 2001 From: "Andrey M. Borodin" Date: Sat, 18 May 2024 23:02:50 +0500 Subject: [PATCH v7] Use specialized sort facilities --- contrib/intarray/_int.h | 17 ++++---- contrib/intarray/_int_tool.c | 79 +++++++++++++++++------------------- 2 files changed, 46 insertions(+), 50 deletions(-) diff --git a/contrib/intarray/_int.h b/contrib/intarray/_int.h index 0352cbd368..1da2f36f99 100644 --- a/contrib/intarray/_int.h +++ b/contrib/intarray/_int.h @@ -22,6 +22,8 @@ typedef struct int num_ranges; /* number of ranges */ } GISTIntArrayOptions; +extern void sort_int32(int32 *base, size_t nel, bool ascending); + /* useful macros for accessing int4 arrays */ #define ARRPTR(x) ( (int32 *) ARR_DATA_PTR(x) ) #define ARRNELEMS(x) ArrayGetNItems(ARR_NDIM(x), ARR_DIMS(x)) @@ -42,7 +44,7 @@ typedef struct do { \ int _nelems_ = ARRNELEMS(x); \ if (_nelems_ > 1) \ - isort(ARRPTR(x), _nelems_); \ + sort_int32(ARRPTR(x), _nelems_, true); \ } while(0) /* sort the elements of the array and remove duplicates */ @@ -50,8 +52,10 @@ typedef struct do { \ int _nelems_ = ARRNELEMS(x); \ if (_nelems_ > 1) \ - if (isort(ARRPTR(x), _nelems_)) \ - (x) = _int_unique(x); \ + { \ + sort_int32(ARRPTR(x), _nelems_, true); \ + (x) = _int_unique(x); \ + } \ } while(0) /* "wish" function */ @@ -109,7 +113,6 @@ typedef struct /* * useful functions */ -bool isort(int32 *a, int len); ArrayType *new_intArrayType(int num); ArrayType *copy_intArrayType(ArrayType *a); ArrayType *resize_intArrayType(ArrayType *a, int num); @@ -176,16 +179,12 @@ bool execconsistent(QUERYTYPE *query, ArrayType *array, bool calcnot); bool gin_bool_consistent(QUERYTYPE *query, bool *check); bool query_has_required_values(QUERYTYPE *query); -int compASC(const void *a, const void *b); -int compDESC(const void *a, const void *b); - /* sort, either ascending or descending */ #define QSORT(a, direction) \ do { \ int _nelems_ = ARRNELEMS(a); \ if (_nelems_ > 1) \ - qsort((void*) ARRPTR(a), _nelems_, sizeof(int32), \ - (direction) ? compASC : compDESC ); \ + sort_int32(ARRPTR(a), _nelems_, direction); \ } while(0) #endif /* ___INT_H__ */ diff --git a/contrib/intarray/_int_tool.c b/contrib/intarray/_int_tool.c index c85280c842..ea99b2c4de 100644 --- a/contrib/intarray/_int_tool.c +++ b/contrib/intarray/_int_tool.c @@ -10,6 +10,8 @@ #include "common/int.h" #include "lib/qunique.h" +static inline int compASC(const void *a, const void *b); + /* arguments are assumed sorted & unique-ified */ bool inner_int_contains(ArrayType *a, ArrayType *b) @@ -186,37 +188,6 @@ rt__int_size(ArrayType *a, float *size) *size = (float) ARRNELEMS(a); } -/* qsort_arg comparison function for isort() */ -static int -isort_cmp(const void *a, const void *b, void *arg) -{ - int32 aval = *((const int32 *) a); - int32 bval = *((const int32 *) b); - - if (aval < bval) - return -1; - if (aval > bval) - return 1; - - /* - * Report if we have any duplicates. If there are equal keys, qsort must - * compare them at some point, else it wouldn't know whether one should go - * before or after the other. - */ - *((bool *) arg) = true; - return 0; -} - -/* Sort the given data (len >= 2). Return true if any duplicates found */ -bool -isort(int32 *a, int len) -{ - bool r = false; - - qsort_arg(a, len, sizeof(int32), isort_cmp, &r); - return r; -} - /* Create a new int array with room for "num" elements */ ArrayType * new_intArrayType(int num) @@ -306,15 +277,47 @@ internal_size(int *a, int len) return (int) size; } +static inline int +sort_int32_cmp(int32* a, int32* b, bool* ascending) +{ + if (*ascending) + { + if (*a < *b) + return -1; + if (*a > *b) + return 1; + } + else + { + if (*a < *b) + return 1; + if (*a > *b) + return -1; + } + return 0; +} + +#define ST_SORT sort_int32_impl +#define ST_ELEMENT_TYPE int32 +#define ST_COMPARE(a, b, ascending) sort_int32_cmp(a, b, ascending) +#define ST_COMPARE_ARG_TYPE bool +#define ST_SCOPE static +#define ST_DECLARE +#define ST_DEFINE +#include "lib/sort_template.h" + +void sort_int32(int32 *base, size_t nel, bool ascending) +{ + sort_int32_impl(base, nel, &ascending); +} + /* unique-ify elements of r in-place ... r must be sorted already */ ArrayType * _int_unique(ArrayType *r) { int num = ARRNELEMS(r); - bool duplicates_found; /* not used */ - num = qunique_arg(ARRPTR(r), num, sizeof(int), isort_cmp, - &duplicates_found); + num = qunique(ARRPTR(r), num, sizeof(int), compASC); return resize_intArrayType(r, num); } @@ -394,14 +397,8 @@ int_to_intset(int32 elem) return result; } -int +static inline int compASC(const void *a, const void *b) { return pg_cmp_s32(*(const int32 *) a, *(const int32 *) b); } - -int -compDESC(const void *a, const void *b) -{ - return pg_cmp_s32(*(const int32 *) b, *(const int32 *) a); -} -- 2.39.5 (Apple Git-154)