Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+33-42
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)