From 04474538aff8b3135035e7671d9639164c336a0b Mon Sep 17 00:00:00 2001
From: John Naylor <john.naylor@postgresql.org>
Date: Wed, 18 Aug 2021 13:04:56 -0400
Subject: [PATCH v1 4/6] Rationalize rehashing threshold

Rehash catcache when the average length of the conflict list is one
greater than the capacity of the L1
---
 src/backend/utils/cache/catcache.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index dad985fc5a..e53d4325ab 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -1908,6 +1908,7 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 	HeapTuple	dtp;
 	MemoryContext oldcxt;
 	CCBucket	bucket = cache->cc_bucket[hashIndex];
+	int			rehash_threshold;
 
 	/* negative entries have no tuple associated */
 	if (ntp)
@@ -1994,9 +1995,25 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
 
 	/*
 	 * If the hash table has become too full, enlarge the buckets array. Quite
-	 * arbitrarily, we enlarge when fill factor > 2.
+	 * arbitrarily, we enlarge when fill factor > (1 + max num entries in L1).
+	 * XXX magic constants -- find a better way.
 	 */
-	if (cache->cc_ntup > cache->cc_nbuckets * 2)
+	switch (cache->cc_nkeys)
+	{
+		case 1:
+			rehash_threshold = 6;
+		case 2:
+			rehash_threshold = 5;
+		case 3:
+			rehash_threshold = 4;
+		case 4:
+			rehash_threshold = 3;
+		default:
+			/* apparently cc_nkeys is not set during bootstrap */
+			rehash_threshold = 2;
+	}
+
+	if (cache->cc_ntup > cache->cc_nbuckets * rehash_threshold)
 		RehashCatCache(cache);
 
 	return ct;
-- 
2.31.1

