From a169a7fd7fb197f42260db2f79bffbc29bb49cfc Mon Sep 17 00:00:00 2001 From: John Naylor Date: Wed, 18 Aug 2021 12:03:46 -0400 Subject: [PATCH v1 2/6] Specialize bucket types by number of keys Don't do anything special with the bucket types yet, that will come in a later commit. --- src/backend/utils/cache/catcache.c | 40 ++++++++++++++++------------ src/include/utils/catcache.h | 42 +++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 47fb14e1db..55ea4b0339 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -556,6 +556,7 @@ void CatCacheInvalidate(CatCache *cache, uint32 hashValue) { Index hashIndex; + CCBucket bucket; dlist_mutable_iter iter; CACHE_elog(DEBUG2, "CatCacheInvalidate: called"); @@ -583,7 +584,8 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue) * inspect the proper hash bucket for tuple matches */ hashIndex = HASH_INDEX(hashValue, cache->cc_nbuckets); - dlist_foreach_modify(iter, &cache->cc_bucket[hashIndex]) + bucket = cache->cc_bucket[hashIndex]; + dlist_foreach_modify(iter, &bucket.conflicts) { CatCTup *ct = dlist_container(CatCTup, cache_elem, iter.cur); @@ -664,9 +666,9 @@ ResetCatalogCache(CatCache *cache) /* Remove each tuple in this cache, or at least mark it dead */ for (i = 0; i < cache->cc_nbuckets; i++) { - dlist_head *bucket = &cache->cc_bucket[i]; + CCBucket bucket = cache->cc_bucket[i]; - dlist_foreach_modify(iter, bucket) + dlist_foreach_modify(iter, &bucket.conflicts) { CatCTup *ct = dlist_container(CatCTup, cache_elem, iter.cur); @@ -818,11 +820,12 @@ InitCatCache(int id, /* * Allocate a new cache structure, aligning to a cacheline boundary * - * Note: we rely on zeroing to initialize all the dlist headers correctly + * Note: we rely on zeroing to initialize all the bucket elements + * correctly */ sz = sizeof(CatCache) + PG_CACHE_LINE_SIZE; cp = (CatCache *) CACHELINEALIGN(palloc0(sz)); - cp->cc_bucket = palloc0(nbuckets * sizeof(dlist_head)); + cp->cc_bucket = palloc0(nbuckets * sizeof(CCBucket)); /* * initialize the cache's relation information for the relation @@ -866,7 +869,8 @@ InitCatCache(int id, static void RehashCatCache(CatCache *cp) { - dlist_head *newbucket; + CCBucket *oldbucket = cp->cc_bucket; + CCBucket *newbucket; int newnbuckets; int i; @@ -875,20 +879,20 @@ RehashCatCache(CatCache *cp) /* Allocate a new, larger, hash table. */ newnbuckets = cp->cc_nbuckets * 2; - newbucket = (dlist_head *) MemoryContextAllocZero(CacheMemoryContext, newnbuckets * sizeof(dlist_head)); + newbucket = (CCBucket *) MemoryContextAllocZero(CacheMemoryContext, newnbuckets * sizeof(CCBucket)); /* Move all entries from old hash table to new. */ for (i = 0; i < cp->cc_nbuckets; i++) { dlist_mutable_iter iter; - dlist_foreach_modify(iter, &cp->cc_bucket[i]) + dlist_foreach_modify(iter, &oldbucket[i].conflicts) { CatCTup *ct = dlist_container(CatCTup, cache_elem, iter.cur); int hashIndex = HASH_INDEX(ct->hash_value, newnbuckets); dlist_delete(iter.cur); - dlist_push_head(&newbucket[hashIndex], &ct->cache_elem); + dlist_push_head(&newbucket[hashIndex].conflicts, &ct->cache_elem); } } @@ -1215,7 +1219,7 @@ SearchCatCacheInternal(CatCache *cache, uint32 hashValue; Index hashIndex; dlist_iter iter; - dlist_head *bucket; + CCBucket bucket; CatCTup *ct; /* Make sure we're in an xact, even if this ends up being a cache hit */ @@ -1251,8 +1255,9 @@ SearchCatCacheInternal(CatCache *cache, * Note: it's okay to use dlist_foreach here, even though we modify the * dlist within the loop, because we don't continue the loop afterwards. */ - bucket = &cache->cc_bucket[hashIndex]; - dlist_foreach(iter, bucket) + bucket = cache->cc_bucket[hashIndex]; + + dlist_foreach(iter, &bucket.conflicts) { ct = dlist_container(CatCTup, cache_elem, iter.cur); @@ -1268,7 +1273,7 @@ SearchCatCacheInternal(CatCache *cache, * most frequently accessed elements in any hashbucket will tend to be * near the front of the hashbucket's list.) */ - dlist_move_head(bucket, &ct->cache_elem); + dlist_move_head(&bucket.conflicts, &ct->cache_elem); /* * If it's a positive entry, bump its refcount and return it. If it's @@ -1650,7 +1655,7 @@ SearchCatCacheList(CatCache *cache, uint32 hashValue; Index hashIndex; bool found = false; - dlist_head *bucket; + CCBucket bucket; /* * See if there's an entry for this tuple already. @@ -1659,8 +1664,8 @@ SearchCatCacheList(CatCache *cache, hashValue = CatalogCacheComputeTupleHashValue(cache, cache->cc_nkeys, ntp); hashIndex = HASH_INDEX(hashValue, cache->cc_nbuckets); - bucket = &cache->cc_bucket[hashIndex]; - dlist_foreach(iter, bucket) + bucket = cache->cc_bucket[hashIndex]; + dlist_foreach(iter, &bucket.conflicts) { ct = dlist_container(CatCTup, cache_elem, iter.cur); @@ -1811,6 +1816,7 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments, CatCTup *ct; HeapTuple dtp; MemoryContext oldcxt; + CCBucket bucket = cache->cc_bucket[hashIndex]; /* negative entries have no tuple associated */ if (ntp) @@ -1890,7 +1896,7 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments, ct->negative = negative; ct->hash_value = hashValue; - dlist_push_head(&cache->cc_bucket[hashIndex], &ct->cache_elem); + dlist_push_head(&bucket.conflicts, &ct->cache_elem); cache->cc_ntup++; CacheHdr->ch_ntup++; diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h index eac6a83f29..b870816a72 100644 --- a/src/include/utils/catcache.h +++ b/src/include/utils/catcache.h @@ -41,12 +41,52 @@ typedef uint32 (*CCHashFN) (Datum datum); /* function computing equality of two datums */ typedef bool (*CCFastEqualFN) (Datum a, Datum b); +typedef struct bucket1 +{ + uint32 hashes[5]; + Datum keys[5][1]; + struct catctup *ct[5]; +} Bucket1; + +typedef struct bucket2 +{ + uint32 hashes[4]; + Datum keys[4][2]; + struct catctup *ct[4]; +} Bucket2; + +typedef struct bucket3 +{ + uint32 hashes[3]; + Datum keys[3][3]; + struct catctup *ct[3]; +} Bucket3; + +typedef struct bucket4 +{ + uint32 hashes[2]; + Datum keys[2][4]; + struct catctup *ct[2]; +} Bucket4; + +typedef struct cc_bucket +{ + union + { + Bucket1 bucket1; + Bucket2 bucket2; + Bucket3 bucket3; + Bucket4 bucket4; + }; + dlist_head conflicts; +} CCBucket; + typedef struct catcache { int id; /* cache identifier --- see syscache.h */ int cc_nbuckets; /* # of hash buckets in this cache */ TupleDesc cc_tupdesc; /* tuple descriptor (copied from reldesc) */ - dlist_head *cc_bucket; /* hash buckets */ + CCBucket *cc_bucket; /* hash buckets */ CCHashFN cc_hashfunc[CATCACHE_MAXKEYS]; /* hash function for each key */ CCFastEqualFN cc_fastequal[CATCACHE_MAXKEYS]; /* fast equal function for * each key */ -- 2.31.1