summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeikki Linnakangas2023-11-08 11:30:52 +0000
committerHeikki Linnakangas2023-11-08 11:30:52 +0000
commit954e43564d9920f0a98e3b750e0c74bb035410f5 (patch)
tree4736ac4d3f41055e788531b8a4c2814da1142a6e
parentb8bff07daa85c837a2747b4d35cd5a27e73fb7b2 (diff)
Use a faster hash function in resource owners.
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
-rw-r--r--src/backend/utils/resowner/resowner.c24
-rw-r--r--src/include/common/hashfn.h15
2 files changed, 33 insertions, 6 deletions
diff --git a/src/backend/utils/resowner/resowner.c b/src/backend/utils/resowner/resowner.c
index 6e4020f241f..eecb3ade3d7 100644
--- a/src/backend/utils/resowner/resowner.c
+++ b/src/backend/utils/resowner/resowner.c
@@ -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
}
/*
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 */