Use a faster hash function in resource owners.
authorHeikki Linnakangas
Wed, 8 Nov 2023 11:30:52 +0000 (13:30 +0200)
committerHeikki Linnakangas
Wed, 8 Nov 2023 11:30:52 +0000 (13:30 +0200)
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
src/include/common/hashfn.h

index 6e4020f241fdd08b0070da4f69ecc346ed4c8c05..eecb3ade3d7c06969f0f5d501881ddc2644dd680 100644 (file)
@@ -206,15 +206,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
 }
 
 /*
index 5e89aef987f1bd8ec43683fa0edeee54873b5275..adc1dc1de89da432d31a43265663809835814c24 100644 (file)
@@ -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 */