From 39354c4ee3bdf837b0c9a09aafaf64640a0a086e Mon Sep 17 00:00:00 2001 From: "Andrey M. Borodin" Date: Sat, 18 May 2024 23:02:50 +0500 Subject: [PATCH v1] Use specialized sort facilities --- contrib/intarray/_int.h | 12 ------------ contrib/intarray/_int_gist.c | 2 +- contrib/intarray/_int_op.c | 19 +++++++++---------- contrib/intarray/_int_tool.c | 12 ------------ src/include/port.h | 2 ++ src/port/qsort.c | 35 +++++++++++++++++++++++++++++++++++ 6 files changed, 47 insertions(+), 35 deletions(-) diff --git a/contrib/intarray/_int.h b/contrib/intarray/_int.h index 0352cbd3682..5225c9090a8 100644 --- a/contrib/intarray/_int.h +++ b/contrib/intarray/_int.h @@ -176,16 +176,4 @@ 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 ); \ - } while(0) - #endif /* ___INT_H__ */ diff --git a/contrib/intarray/_int_gist.c b/contrib/intarray/_int_gist.c index a09b7fa812c..d39e40c66aa 100644 --- a/contrib/intarray/_int_gist.c +++ b/contrib/intarray/_int_gist.c @@ -150,7 +150,7 @@ g_int_union(PG_FUNCTION_ARGS) ptr += nel; } - QSORT(res, 1); + sort_int32_asc(ARRPTR(res), ARRNELEMS(res)); res = _int_unique(res); *size = VARSIZE(res); PG_RETURN_POINTER(res); diff --git a/contrib/intarray/_int_op.c b/contrib/intarray/_int_op.c index 5b164f6788f..34d3aa183f8 100644 --- a/contrib/intarray/_int_op.c +++ b/contrib/intarray/_int_op.c @@ -198,7 +198,6 @@ sort(PG_FUNCTION_ARGS) text *dirstr = (fcinfo->nargs == 2) ? PG_GETARG_TEXT_PP(1) : NULL; int32 dc = (dirstr) ? VARSIZE_ANY_EXHDR(dirstr) : 0; char *d = (dirstr) ? VARDATA_ANY(dirstr) : NULL; - int dir = -1; CHECKARRVALID(a); if (ARRNELEMS(a) < 2) @@ -208,18 +207,18 @@ sort(PG_FUNCTION_ARGS) && (d[0] == 'A' || d[0] == 'a') && (d[1] == 'S' || d[1] == 's') && (d[2] == 'C' || d[2] == 'c'))) - dir = 1; + sort_int32_asc(ARRPTR(a), ARRNELEMS(a)); else if (dc == 4 && (d[0] == 'D' || d[0] == 'd') && (d[1] == 'E' || d[1] == 'e') && (d[2] == 'S' || d[2] == 's') && (d[3] == 'C' || d[3] == 'c')) - dir = 0; - if (dir == -1) + sort_int32_desc(ARRPTR(a), ARRNELEMS(a)); + else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("second parameter must be \"ASC\" or \"DESC\""))); - QSORT(a, dir); + PG_RETURN_POINTER(a); } @@ -229,7 +228,7 @@ sort_asc(PG_FUNCTION_ARGS) ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0); CHECKARRVALID(a); - QSORT(a, 1); + sort_int32_asc(ARRPTR(a), ARRNELEMS(a)); PG_RETURN_POINTER(a); } @@ -239,7 +238,7 @@ sort_desc(PG_FUNCTION_ARGS) ArrayType *a = PG_GETARG_ARRAYTYPE_P_COPY(0); CHECKARRVALID(a); - QSORT(a, 0); + sort_int32_desc(ARRPTR(a), ARRNELEMS(a)); PG_RETURN_POINTER(a); } @@ -381,7 +380,7 @@ intset_union_elem(PG_FUNCTION_ARGS) result = intarray_add_elem(a, PG_GETARG_INT32(1)); PG_FREE_IF_COPY(a, 0); - QSORT(result, 1); + sort_int32_asc(ARRPTR(result), ARRNELEMS(result)); PG_RETURN_POINTER(_int_unique(result)); } @@ -403,10 +402,10 @@ intset_subtract(PG_FUNCTION_ARGS) CHECKARRVALID(a); CHECKARRVALID(b); - QSORT(a, 1); + sort_int32_asc(ARRPTR(a), ARRNELEMS(a)); a = _int_unique(a); ca = ARRNELEMS(a); - QSORT(b, 1); + sort_int32_asc(ARRPTR(b), ARRNELEMS(b)); b = _int_unique(b); cb = ARRNELEMS(b); result = new_intArrayType(ca); diff --git a/contrib/intarray/_int_tool.c b/contrib/intarray/_int_tool.c index c85280c8422..e83c6aadc6c 100644 --- a/contrib/intarray/_int_tool.c +++ b/contrib/intarray/_int_tool.c @@ -393,15 +393,3 @@ int_to_intset(int32 elem) 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); -} diff --git a/src/include/port.h b/src/include/port.h index ae115d2d970..b48194cb004 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -445,6 +445,8 @@ extern bool pg_get_user_home_dir(uid_t user_id, char *buffer, size_t buflen); 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_asc(int32 *base, size_t nel); +extern void sort_int32_desc(int32 *base, size_t nel); #define qsort(a,b,c,d) pg_qsort(a,b,c,d) diff --git a/src/port/qsort.c b/src/port/qsort.c index 7879e6cd563..5175c8a6dde 100644 --- a/src/port/qsort.c +++ b/src/port/qsort.c @@ -20,3 +20,38 @@ pg_qsort_strcmp(const void *a, const void *b) { return strcmp(*(const char *const *) a, *(const char *const *) b); } + +static inline int +sort_int32_asc_cmp(int32* a, int32* b) +{ + if (*a < *b) + return -1; + if (*a > *b) + return 1; + return 0; +} + +#define ST_SORT sort_int32_asc +#define ST_ELEMENT_TYPE int32 +#define ST_COMPARE sort_int32_asc_cmp +#define ST_SCOPE +#define ST_DECLARE +#define ST_DEFINE +#include "lib/sort_template.h" + +static inline int +sort_int32_desc_cmp(int32* a, int32* b) +{ + if (*a < *b) + return 1; + if (*a > *b) + return -1; + return 0; +} +#define ST_SORT sort_int32_desc +#define ST_ELEMENT_TYPE int32 +#define ST_COMPARE sort_int32_desc_cmp +#define ST_SCOPE +#define ST_DECLARE +#define ST_DEFINE +#include "lib/sort_template.h" -- 2.37.1 (Apple Git-137.1)