aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-04-21 04:49:20 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-04-21 04:49:20 +0000
commit402bd494ce98dc263a102da99b10c2e1d6a1460d (patch)
treed7554dbd89041e7b21bf7fdf7050b133846b6155 /src/backend
parent11da4c671ea6391c59ed5f465e390c6635e54cf4 (diff)
downloadpostgresql-402bd494ce98dc263a102da99b10c2e1d6a1460d.tar.gz
postgresql-402bd494ce98dc263a102da99b10c2e1d6a1460d.zip
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?
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/utils/cache/catcache.c24
1 files 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);