v2-0001-Add-sort-support-for-point-gist_point_sortsupport.patch

application/octet-stream

Filename: v2-0001-Add-sort-support-for-point-gist_point_sortsupport.patch
Type: application/octet-stream
Part: 0
Message: Re: Yet another fast GiST build

Patch

Format: format-patch
Series: patch v2-0001
Subject: Add sort support for point gist_point_sortsupport
File+
src/backend/access/gist/gistproc.c 53 0
src/include/catalog/pg_proc.dat 3 0
From 3f9d4f0b407339f9e40fc4ccc39d594f95ac84ca Mon Sep 17 00:00:00 2001
From: Andrey <amborodin@acm.org>
Date: Sun, 25 Aug 2019 12:42:36 +0500
Subject: [PATCH 1/2] Add sort support for point  gist_point_sortsupport

---
 src/backend/access/gist/gistproc.c | 53 ++++++++++++++++++++++++++++++
 src/include/catalog/pg_proc.dat    |  3 ++
 2 files changed, 56 insertions(+)

diff --git a/src/backend/access/gist/gistproc.c b/src/backend/access/gist/gistproc.c
index 1826b51bbb..e53c63dc2b 100644
--- a/src/backend/access/gist/gistproc.c
+++ b/src/backend/access/gist/gistproc.c
@@ -24,6 +24,7 @@
 #include "utils/builtins.h"
 #include "utils/float.h"
 #include "utils/geo_decls.h"
+#include "utils/sortsupport.h"
 
 
 static bool gist_box_leaf_consistent(BOX *key, BOX *query,
@@ -1530,3 +1531,55 @@ gist_poly_distance(PG_FUNCTION_ARGS)
 
 	PG_RETURN_FLOAT8(distance);
 }
+
+static int64
+part_bits32_by2(uint32 x)
+{
+	uint64		n = x;
+
+	n = (n | (n << 16)) & 0x0000FFFF0000FFFF;
+	n = (n | (n <<  8)) & 0x00FF00FF00FF00FF;
+	n = (n | (n <<  4)) & 0x0F0F0F0F0F0F0F0F;
+	n = (n | (n <<  2)) & 0x3333333333333333;
+	n = (n | (n <<  1)) & 0x5555555555555555;
+
+	return n;
+}
+
+static int64
+interleave_bits32(uint32 x, uint32 y)
+{
+	return part_bits32_by2(x) | (part_bits32_by2(y) << 1);
+}
+
+static inline uint64
+point_zorder_internal(Point *p)
+{
+	union {
+		float f;
+		uint32 i;
+	} a,b;
+	a.f = p->x;
+	b.f = p->y;
+	return interleave_bits32(a.i, b.i);
+}
+
+static int
+gist_point_fastcmp(Datum x, Datum y, SortSupport ssup)
+{
+	Point	*p1 = DatumGetPointP(x);
+	Point	*p2 = DatumGetPointP(y);
+	uint64	 z1 = point_zorder_internal(p1);
+	uint64	 z2 = point_zorder_internal(p2);
+
+	return z1 == z2 ? 0 : z1 > z2 ? 1 : -1;
+}
+
+Datum
+gist_point_sortsupport(PG_FUNCTION_ARGS)
+{
+	SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
+
+	ssup->comparator = gist_point_fastcmp;
+	PG_RETURN_VOID();
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 87335248a0..de3cb2f1e3 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -7849,6 +7849,9 @@
   proname => 'gist_poly_distance', prorettype => 'float8',
   proargtypes => 'internal polygon int2 oid internal',
   prosrc => 'gist_poly_distance' },
+{ oid => '3429', descr => 'sort support',
+  proname => 'gist_point_sortsupport', prorettype => 'void',
+  proargtypes => 'internal', prosrc => 'gist_point_sortsupport' },
 
 # GIN array support
 { oid => '2743', descr => 'GIN array support',
-- 
2.20.1