aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-06-01 15:58:09 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-06-01 15:58:09 +0000
commit38bbcb3888d8d93dfc369fbbac49888860596010 (patch)
tree18deb70ac768ef7925b8dc008b96877ab8ee80f3 /src/backend/access
parent4c2158bf0c309099c1d185405b3d10d41708eb2e (diff)
downloadpostgresql-38bbcb3888d8d93dfc369fbbac49888860596010.tar.gz
postgresql-38bbcb3888d8d93dfc369fbbac49888860596010.zip
Fix performance problems in multi-batch hash joins by ensuring that we select
a well-randomized batch number even when given a poorly-randomized hash value. This is a bit inefficient but seems the only practical solution given the constraint that we can't change the hash functions in released branches. Per report from Joseph Shraibman. Applied to 8.1 and 8.2 only --- HEAD is getting a cleaner fix, and 8.0 and before use different coding that seems less vulnerable.
Diffstat (limited to 'src/backend/access')
-rw-r--r--src/backend/access/hash/hashfunc.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/backend/access/hash/hashfunc.c b/src/backend/access/hash/hashfunc.c
index a4803708ad4..f03df3d5999 100644
--- a/src/backend/access/hash/hashfunc.c
+++ b/src/backend/access/hash/hashfunc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/hash/hashfunc.c,v 1.45.2.1 2005/12/22 22:50:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/hash/hashfunc.c,v 1.45.2.2 2007/06/01 15:58:09 tgl Exp $
*
* NOTES
* These functions are stored in pg_amproc. For each operator class
@@ -267,6 +267,31 @@ hash_any(register const unsigned char *k, register int keylen)
/* case 0: nothing left to add */
}
mix(a, b, c);
+
+ /* report the result */
+ return UInt32GetDatum(c);
+}
+
+/*
+ * hash_uint32() -- hash a 32-bit value
+ *
+ * This has the same result (at least on little-endian machines) as
+ * hash_any(&k, sizeof(uint32))
+ * but is faster and doesn't force the caller to store k into memory.
+ */
+Datum
+hash_uint32(uint32 k)
+{
+ register uint32 a,
+ b,
+ c;
+
+ a = 0x9e3779b9 + k;
+ b = 0x9e3779b9;
+ c = 3923095 + (uint32) sizeof(uint32);
+
+ mix(a, b, c);
+
/* report the result */
return UInt32GetDatum(c);
}