Skip to content

Commit cc5ef90

Browse files
committed
Refactor initial hash lookup in dynahash.c
The same pattern is used three times in dynahash.c to retrieve a bucket number and a hash bucket from a hash value. This has popped up while discussing improvements for the type cache, where this piece of refactoring would become useful. Note that hash_search_with_hash_value() does not need the bucket number, just the hash bucket. Author: Teodor Sigaev Reviewed-by: Aleksander Alekseev, Michael Paquier Discussion: https://postgr.es/m/5812a6e5-68ae-4d84-9d85-b443176966a1@sigaev.ru
1 parent 4169850 commit cc5ef90

File tree

1 file changed

+33
-42
lines changed

1 file changed

+33
-42
lines changed

src/backend/utils/hash/dynahash.c

Lines changed: 33 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ static void hdefault(HTAB *hashp);
273273
static int choose_nelem_alloc(Size entrysize);
274274
static bool init_htab(HTAB *hashp, long nelem);
275275
static void hash_corrupted(HTAB *hashp);
276+
static uint32 hash_initial_lookup(HTAB *hashp, uint32 hashvalue,
277+
HASHBUCKET **bucketptr);
276278
static long next_pow2_long(long num);
277279
static int next_pow2_int(long num);
278280
static void register_seq_scan(HTAB *hashp);
@@ -972,10 +974,6 @@ hash_search_with_hash_value(HTAB *hashp,
972974
HASHHDR *hctl = hashp->hctl;
973975
int freelist_idx = FREELIST_IDX(hctl, hashvalue);
974976
Size keysize;
975-
uint32 bucket;
976-
long segment_num;
977-
long segment_ndx;
978-
HASHSEGMENT segp;
979977
HASHBUCKET currBucket;
980978
HASHBUCKET *prevBucketPtr;
981979
HashCompareFunc match;
@@ -1008,17 +1006,7 @@ hash_search_with_hash_value(HTAB *hashp,
10081006
/*
10091007
* Do the initial lookup
10101008
*/
1011-
bucket = calc_bucket(hctl, hashvalue);
1012-
1013-
segment_num = bucket >> hashp->sshift;
1014-
segment_ndx = MOD(bucket, hashp->ssize);
1015-
1016-
segp = hashp->dir[segment_num];
1017-
1018-
if (segp == NULL)
1019-
hash_corrupted(hashp);
1020-
1021-
prevBucketPtr = &segp[segment_ndx];
1009+
(void) hash_initial_lookup(hashp, hashvalue, &prevBucketPtr);
10221010
currBucket = *prevBucketPtr;
10231011

10241012
/*
@@ -1159,14 +1147,10 @@ hash_update_hash_key(HTAB *hashp,
11591147
const void *newKeyPtr)
11601148
{
11611149
HASHELEMENT *existingElement = ELEMENT_FROM_KEY(existingEntry);
1162-
HASHHDR *hctl = hashp->hctl;
11631150
uint32 newhashvalue;
11641151
Size keysize;
11651152
uint32 bucket;
11661153
uint32 newbucket;
1167-
long segment_num;
1168-
long segment_ndx;
1169-
HASHSEGMENT segp;
11701154
HASHBUCKET currBucket;
11711155
HASHBUCKET *prevBucketPtr;
11721156
HASHBUCKET *oldPrevPtr;
@@ -1187,17 +1171,8 @@ hash_update_hash_key(HTAB *hashp,
11871171
* this to be able to unlink it from its hash chain, but as a side benefit
11881172
* we can verify the validity of the passed existingEntry pointer.
11891173
*/
1190-
bucket = calc_bucket(hctl, existingElement->hashvalue);
1191-
1192-
segment_num = bucket >> hashp->sshift;
1193-
segment_ndx = MOD(bucket, hashp->ssize);
1194-
1195-
segp = hashp->dir[segment_num];
1196-
1197-
if (segp == NULL)
1198-
hash_corrupted(hashp);
1199-
1200-
prevBucketPtr = &segp[segment_ndx];
1174+
bucket = hash_initial_lookup(hashp, existingElement->hashvalue,
1175+
&prevBucketPtr);
12011176
currBucket = *prevBucketPtr;
12021177

12031178
while (currBucket != NULL)
@@ -1219,18 +1194,7 @@ hash_update_hash_key(HTAB *hashp,
12191194
* chain we want to put the entry into.
12201195
*/
12211196
newhashvalue = hashp->hash(newKeyPtr, hashp->keysize);
1222-
1223-
newbucket = calc_bucket(hctl, newhashvalue);
1224-
1225-
segment_num = newbucket >> hashp->sshift;
1226-
segment_ndx = MOD(newbucket, hashp->ssize);
1227-
1228-
segp = hashp->dir[segment_num];
1229-
1230-
if (segp == NULL)
1231-
hash_corrupted(hashp);
1232-
1233-
prevBucketPtr = &segp[segment_ndx];
1197+
newbucket = hash_initial_lookup(hashp, newhashvalue, &prevBucketPtr);
12341198
currBucket = *prevBucketPtr;
12351199

12361200
/*
@@ -1741,6 +1705,33 @@ element_alloc(HTAB *hashp, int nelem, int freelist_idx)
17411705
return true;
17421706
}
17431707

1708+
/*
1709+
* Do initial lookup of a bucket for the given hash value, retrieving its
1710+
* bucket number and its hash bucket.
1711+
*/
1712+
static inline uint32
1713+
hash_initial_lookup(HTAB *hashp, uint32 hashvalue, HASHBUCKET **bucketptr)
1714+
{
1715+
HASHHDR *hctl = hashp->hctl;
1716+
HASHSEGMENT segp;
1717+
long segment_num;
1718+
long segment_ndx;
1719+
uint32 bucket;
1720+
1721+
bucket = calc_bucket(hctl, hashvalue);
1722+
1723+
segment_num = bucket >> hashp->sshift;
1724+
segment_ndx = MOD(bucket, hashp->ssize);
1725+
1726+
segp = hashp->dir[segment_num];
1727+
1728+
if (segp == NULL)
1729+
hash_corrupted(hashp);
1730+
1731+
*bucketptr = &segp[segment_ndx];
1732+
return bucket;
1733+
}
1734+
17441735
/* complain when we have detected a corrupted hashtable */
17451736
static void
17461737
hash_corrupted(HTAB *hashp)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy