From be4e7c85cad0e6f9d7289f38c20cc581fc50eb62 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 v3] Use specialized sort facilities

---
 contrib/intarray/_int.h      |  8 +---
 contrib/intarray/_int_tool.c | 14 +------
 src/include/port.h           |  1 +
 src/port/qsort.c             | 73 ++++++++++++++++++++++++++++++++++++
 4 files changed, 77 insertions(+), 19 deletions(-)

diff --git a/contrib/intarray/_int.h b/contrib/intarray/_int.h
index 0352cbd368..fb965cb035 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 */
@@ -176,16 +176,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..c49097bc7d 100644
--- a/contrib/intarray/_int_tool.c
+++ b/contrib/intarray/_int_tool.c
@@ -392,16 +392,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/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)
 
diff --git a/src/port/qsort.c b/src/port/qsort.c
index 7879e6cd56..a3c43c0dd0 100644
--- a/src/port/qsort.c
+++ b/src/port/qsort.c
@@ -20,3 +20,76 @@ pg_qsort_strcmp(const void *a, const void *b)
 {
 	return strcmp(*(const char *const *) a, *(const char *const *) b);
 }
+
+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;
+}
+
+static inline int
+sort_int32_cmp_2(int* a, int* b, bool* ascending)
+{
+	int result;
+
+	if (*a < *b)
+		result = -1;
+	else if (*a > *b)
+		result = 1;
+	else
+		result = 0;
+
+	if (!*ascending)
+		result = -result;
+
+	return result;
+}
+
+static inline int
+sort_int32_cmp_3(int* a, int* b, bool* ascending)
+{
+	int result;
+	bool asc = *ascending;
+
+	if (*a < *b)
+		result = -1;
+	else if (*a > *b)
+		result = 1;
+	else
+		result = 0;
+
+	if (!asc)
+		result = -result;
+
+	return result;
+}
+
+#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(a, b, ascending) sort_int32_cmp_2(a, b, ascending)
+//#define ST_COMPARE(a, b, ascending) sort_int32_cmp_3(a, b, ascending)
+#define ST_COMPARE_ARG_TYPE bool
+#define ST_SCOPE
+#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);
+}
-- 
2.39.5 (Apple Git-154)

