v16-0003-Use-a-faster-hash-function-in-resource-owners.patch

text/x-patch

Filename: v16-0003-Use-a-faster-hash-function-in-resource-owners.patch
Type: text/x-patch
Part: 2
Message: Re: ResourceOwner refactoring

Patch

Format: format-patch
Series: patch v16-0003
Subject: Use a faster hash function in resource owners.
File+
src/backend/utils/resowner/resowner.c 18 6
src/include/common/hashfn.h 15 0
From 72d1018b09746252d23ea852c7f6bf80db135335 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Mon, 31 Oct 2022 10:49:06 +0100
Subject: [PATCH v16 3/4] Use a faster hash function in resource owners.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This buys back some of the performance loss that we otherwise saw from the
previous commit.

Reviewed-by: Aleksander Alekseev, Michael Paquier, Julien Rouhaud
Reviewed-by: Kyotaro Horiguchi, Hayato Kuroda, Álvaro Herrera, Zhihong Yu
Reviewed-by: Peter Eisentraut, Andres Freund
Discussion: https://www.postgresql.org/message-id/d746cead-a1ef-7efe-fb47-933311e876a3%40iki.fi
---
 src/backend/utils/resowner/resowner.c | 24 ++++++++++++++++++------
 src/include/common/hashfn.h           | 15 +++++++++++++++
 2 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/src/backend/utils/resowner/resowner.c b/src/backend/utils/resowner/resowner.c
index 081342145b6..a0029831cc1 100644
--- a/src/backend/utils/resowner/resowner.c
+++ b/src/backend/utils/resowner/resowner.c
@@ -205,15 +205,27 @@ static void ReleaseAuxProcessResourcesCallback(int code, Datum arg);
  *	  INTERNAL ROUTINES														 *
  *****************************************************************************/
 
+/*
+ * Hash function for value+kind combination.
+ */
 static inline uint32
 hash_resource_elem(Datum value, const ResourceOwnerDesc *kind)
 {
-	Datum		data[2];
-
-	data[0] = value;
-	data[1] = PointerGetDatum(kind);
-
-	return hash_bytes((unsigned char *) &data, 2 * SIZEOF_DATUM);
+	/*
+	 * Most resource kinds store a pointer in 'value', and pointers are unique
+	 * all on their own.  But some resources store plain integers (Files and
+	 * Buffers as of this writing), so we want to incorporate the 'kind' in
+	 * the hash too, otherwise those resources will collide a lot.  But
+	 * because there are only a few resource kinds like that - and only a few
+	 * resource kinds to begin with - we don't need to work too hard to mix
+	 * 'kind' into the hash.  Just add it with hash_combine(), it perturbs the
+	 * result enough for our purposes.
+	 */
+#if SIZEOF_DATUM == 8
+	return hash_combine64(murmurhash64((uint64) value), (uint64) kind);
+#else
+	return hash_combine(murmurhash32((uint32) value), (uint32) kind);
+#endif
 }
 
 /*
diff --git a/src/include/common/hashfn.h b/src/include/common/hashfn.h
index 5e89aef987f..adc1dc1de89 100644
--- a/src/include/common/hashfn.h
+++ b/src/include/common/hashfn.h
@@ -101,4 +101,19 @@ murmurhash32(uint32 data)
 	return h;
 }
 
+/* 64-bit variant */
+static inline uint64
+murmurhash64(uint64 data)
+{
+	uint64		h = data;
+
+	h ^= h >> 33;
+	h *= 0xff51afd7ed558ccd;
+	h ^= h >> 33;
+	h *= 0xc4ceb9fe1a85ec53;
+	h ^= h >> 33;
+
+	return h;
+}
+
 #endif							/* HASHFN_H */
-- 
2.39.2