From 402bd494ce98dc263a102da99b10c2e1d6a1460d Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 21 Apr 2007 04:49:20 +0000
Subject: [PATCH] Improve the way in which CatalogCacheComputeHashValue
 combines multiple key values: don't throw away perfectly good hash bits, and
 increase the shift distances so as to provide more separation in the common
 case where some of the key values are small integers (and so their hashes are
 too, because hashfunc.c doesn't try all that hard).  This reduces the runtime
 of SearchCatCache by a factor of 4 in an example provided by Greg Stark, in
 which the planner spends a whole lot of time searching the two-key STATRELATT
 cache.  It seems unlikely to hurt in other cases, but maybe we could do even
 better?

---
 src/backend/utils/cache/catcache.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index b1b7930111d..13771c77ebc 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.136 2007/01/05 22:19:42 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.137 2007/04/21 04:49:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -158,6 +158,7 @@ static uint32
 CatalogCacheComputeHashValue(CatCache *cache, int nkeys, ScanKey cur_skey)
 {
 	uint32		hashValue = 0;
+	uint32		oneHash;
 
 	CACHE4_elog(DEBUG2, "CatalogCacheComputeHashValue %s %d %p",
 				cache->cc_relname,
@@ -167,24 +168,31 @@ CatalogCacheComputeHashValue(CatCache *cache, int nkeys, ScanKey cur_skey)
 	switch (nkeys)
 	{
 		case 4:
-			hashValue ^=
+			oneHash =
 				DatumGetUInt32(DirectFunctionCall1(cache->cc_hashfunc[3],
-											  cur_skey[3].sk_argument)) << 9;
+												   cur_skey[3].sk_argument));
+			hashValue ^= oneHash << 24;
+			hashValue ^= oneHash >> 8;
 			/* FALLTHROUGH */
 		case 3:
-			hashValue ^=
+			oneHash =
 				DatumGetUInt32(DirectFunctionCall1(cache->cc_hashfunc[2],
-											  cur_skey[2].sk_argument)) << 6;
+												   cur_skey[2].sk_argument));
+			hashValue ^= oneHash << 16;
+			hashValue ^= oneHash >> 16;
 			/* FALLTHROUGH */
 		case 2:
-			hashValue ^=
+			oneHash =
 				DatumGetUInt32(DirectFunctionCall1(cache->cc_hashfunc[1],
-											  cur_skey[1].sk_argument)) << 3;
+												   cur_skey[1].sk_argument));
+			hashValue ^= oneHash << 8;
+			hashValue ^= oneHash >> 24;
 			/* FALLTHROUGH */
 		case 1:
-			hashValue ^=
+			oneHash =
 				DatumGetUInt32(DirectFunctionCall1(cache->cc_hashfunc[0],
 												   cur_skey[0].sk_argument));
+			hashValue ^= oneHash;
 			break;
 		default:
 			elog(FATAL, "wrong number of hash keys: %d", nkeys);
-- 
GitLab