From 68db077a6970c15d7b13dcb239f6249d72084513 Mon Sep 17 00:00:00 2001
From: "Andrey M. Borodin" <x4mmm@night.local>
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)

