v5-0001-Use-specialized-sort-facilities.patch
application/octet-stream
Filename: v5-0001-Use-specialized-sort-facilities.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v5-0001
Subject: Use specialized sort facilities
| File | + | − |
|---|---|---|
| contrib/intarray/_int.h | 6 | 9 |
| contrib/intarray/_int_tool.c | 12 | 47 |
| src/backend/utils/sort/qsort_interruptible.c | 35 | 0 |
| src/include/port.h | 1 | 0 |
From ff09aab5ab7c2f89cb9b5b3237f2294273e2de16 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 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)