From ff09aab5ab7c2f89cb9b5b3237f2294273e2de16 Mon Sep 17 00:00:00 2001 From: "Andrey M. Borodin" Date: Sat, 18 May 2024 23:02:50 +0500 Subject: [PATCH v5] Use specialized sort facilities --- contrib/intarray/_int.h | 15 ++--- contrib/intarray/_int_tool.c | 59 ++++---------------- src/backend/utils/sort/qsort_interruptible.c | 35 ++++++++++++ src/include/port.h | 1 + 4 files changed, 54 insertions(+), 56 deletions(-) diff --git a/contrib/intarray/_int.h b/contrib/intarray/_int.h index 0352cbd368..3311a415bf 100644 --- a/contrib/intarray/_int.h +++ b/contrib/intarray/_int.h @@ -42,7 +42,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 +50,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 +111,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 +177,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..06f78547a9 100644 --- a/contrib/intarray/_int_tool.c +++ b/contrib/intarray/_int_tool.c @@ -186,37 +186,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 +275,23 @@ internal_size(int *a, int len) return (int) size; } +static int +unique_cmp(const void *a, const void *b) +{ + int32 aval = *((const int32 *) a); + int32 bval = *((const int32 *) b); + + return pg_cmp_s32(aval, bval); +} + + /* 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), unique_cmp); return resize_intArrayType(r, num); } @@ -392,16 +369,4 @@ int_to_intset(int32 elem) aa = ARRPTR(result); aa[0] = elem; return result; -} - -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); -} +} \ No newline at end of file diff --git a/src/backend/utils/sort/qsort_interruptible.c b/src/backend/utils/sort/qsort_interruptible.c index f179b25624..b893c6ba0f 100644 --- a/src/backend/utils/sort/qsort_interruptible.c +++ b/src/backend/utils/sort/qsort_interruptible.c @@ -14,3 +14,38 @@ #define ST_DEFINE #define ST_CHECK_FOR_INTERRUPTS #include "lib/sort_template.h" + +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 +#define ST_CHECK_FOR_INTERRUPTS +#include "lib/sort_template.h" + +void sort_int32(int32 *base, size_t nel, bool ascending) +{ + sort_int32_impl(base, nel, &ascending); +} diff --git a/src/include/port.h b/src/include/port.h index ba9ab0d34f..72dc42daa6 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -443,6 +443,7 @@ extern char *strsep(char **stringp, const char *delim); extern void pg_qsort(void *base, size_t nel, size_t elsize, int (*cmp) (const void *, const void *)); extern int pg_qsort_strcmp(const void *a, const void *b); +extern void sort_int32(int32 *base, size_t nel, bool ascending); #define qsort(a,b,c,d) pg_qsort(a,b,c,d) -- 2.39.5 (Apple Git-154)