mirror of
https://github.com/postgres/postgres.git
synced 2025-04-21 12:05:57 +03:00
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
This commit is contained in:
parent
4169850f0b
commit
cc5ef90edd
@ -273,6 +273,8 @@ static void hdefault(HTAB *hashp);
|
|||||||
static int choose_nelem_alloc(Size entrysize);
|
static int choose_nelem_alloc(Size entrysize);
|
||||||
static bool init_htab(HTAB *hashp, long nelem);
|
static bool init_htab(HTAB *hashp, long nelem);
|
||||||
static void hash_corrupted(HTAB *hashp);
|
static void hash_corrupted(HTAB *hashp);
|
||||||
|
static uint32 hash_initial_lookup(HTAB *hashp, uint32 hashvalue,
|
||||||
|
HASHBUCKET **bucketptr);
|
||||||
static long next_pow2_long(long num);
|
static long next_pow2_long(long num);
|
||||||
static int next_pow2_int(long num);
|
static int next_pow2_int(long num);
|
||||||
static void register_seq_scan(HTAB *hashp);
|
static void register_seq_scan(HTAB *hashp);
|
||||||
@ -972,10 +974,6 @@ hash_search_with_hash_value(HTAB *hashp,
|
|||||||
HASHHDR *hctl = hashp->hctl;
|
HASHHDR *hctl = hashp->hctl;
|
||||||
int freelist_idx = FREELIST_IDX(hctl, hashvalue);
|
int freelist_idx = FREELIST_IDX(hctl, hashvalue);
|
||||||
Size keysize;
|
Size keysize;
|
||||||
uint32 bucket;
|
|
||||||
long segment_num;
|
|
||||||
long segment_ndx;
|
|
||||||
HASHSEGMENT segp;
|
|
||||||
HASHBUCKET currBucket;
|
HASHBUCKET currBucket;
|
||||||
HASHBUCKET *prevBucketPtr;
|
HASHBUCKET *prevBucketPtr;
|
||||||
HashCompareFunc match;
|
HashCompareFunc match;
|
||||||
@ -1008,17 +1006,7 @@ hash_search_with_hash_value(HTAB *hashp,
|
|||||||
/*
|
/*
|
||||||
* Do the initial lookup
|
* Do the initial lookup
|
||||||
*/
|
*/
|
||||||
bucket = calc_bucket(hctl, hashvalue);
|
(void) hash_initial_lookup(hashp, hashvalue, &prevBucketPtr);
|
||||||
|
|
||||||
segment_num = bucket >> hashp->sshift;
|
|
||||||
segment_ndx = MOD(bucket, hashp->ssize);
|
|
||||||
|
|
||||||
segp = hashp->dir[segment_num];
|
|
||||||
|
|
||||||
if (segp == NULL)
|
|
||||||
hash_corrupted(hashp);
|
|
||||||
|
|
||||||
prevBucketPtr = &segp[segment_ndx];
|
|
||||||
currBucket = *prevBucketPtr;
|
currBucket = *prevBucketPtr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1159,14 +1147,10 @@ hash_update_hash_key(HTAB *hashp,
|
|||||||
const void *newKeyPtr)
|
const void *newKeyPtr)
|
||||||
{
|
{
|
||||||
HASHELEMENT *existingElement = ELEMENT_FROM_KEY(existingEntry);
|
HASHELEMENT *existingElement = ELEMENT_FROM_KEY(existingEntry);
|
||||||
HASHHDR *hctl = hashp->hctl;
|
|
||||||
uint32 newhashvalue;
|
uint32 newhashvalue;
|
||||||
Size keysize;
|
Size keysize;
|
||||||
uint32 bucket;
|
uint32 bucket;
|
||||||
uint32 newbucket;
|
uint32 newbucket;
|
||||||
long segment_num;
|
|
||||||
long segment_ndx;
|
|
||||||
HASHSEGMENT segp;
|
|
||||||
HASHBUCKET currBucket;
|
HASHBUCKET currBucket;
|
||||||
HASHBUCKET *prevBucketPtr;
|
HASHBUCKET *prevBucketPtr;
|
||||||
HASHBUCKET *oldPrevPtr;
|
HASHBUCKET *oldPrevPtr;
|
||||||
@ -1187,17 +1171,8 @@ hash_update_hash_key(HTAB *hashp,
|
|||||||
* this to be able to unlink it from its hash chain, but as a side benefit
|
* this to be able to unlink it from its hash chain, but as a side benefit
|
||||||
* we can verify the validity of the passed existingEntry pointer.
|
* we can verify the validity of the passed existingEntry pointer.
|
||||||
*/
|
*/
|
||||||
bucket = calc_bucket(hctl, existingElement->hashvalue);
|
bucket = hash_initial_lookup(hashp, existingElement->hashvalue,
|
||||||
|
&prevBucketPtr);
|
||||||
segment_num = bucket >> hashp->sshift;
|
|
||||||
segment_ndx = MOD(bucket, hashp->ssize);
|
|
||||||
|
|
||||||
segp = hashp->dir[segment_num];
|
|
||||||
|
|
||||||
if (segp == NULL)
|
|
||||||
hash_corrupted(hashp);
|
|
||||||
|
|
||||||
prevBucketPtr = &segp[segment_ndx];
|
|
||||||
currBucket = *prevBucketPtr;
|
currBucket = *prevBucketPtr;
|
||||||
|
|
||||||
while (currBucket != NULL)
|
while (currBucket != NULL)
|
||||||
@ -1219,18 +1194,7 @@ hash_update_hash_key(HTAB *hashp,
|
|||||||
* chain we want to put the entry into.
|
* chain we want to put the entry into.
|
||||||
*/
|
*/
|
||||||
newhashvalue = hashp->hash(newKeyPtr, hashp->keysize);
|
newhashvalue = hashp->hash(newKeyPtr, hashp->keysize);
|
||||||
|
newbucket = hash_initial_lookup(hashp, newhashvalue, &prevBucketPtr);
|
||||||
newbucket = calc_bucket(hctl, newhashvalue);
|
|
||||||
|
|
||||||
segment_num = newbucket >> hashp->sshift;
|
|
||||||
segment_ndx = MOD(newbucket, hashp->ssize);
|
|
||||||
|
|
||||||
segp = hashp->dir[segment_num];
|
|
||||||
|
|
||||||
if (segp == NULL)
|
|
||||||
hash_corrupted(hashp);
|
|
||||||
|
|
||||||
prevBucketPtr = &segp[segment_ndx];
|
|
||||||
currBucket = *prevBucketPtr;
|
currBucket = *prevBucketPtr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1741,6 +1705,33 @@ element_alloc(HTAB *hashp, int nelem, int freelist_idx)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do initial lookup of a bucket for the given hash value, retrieving its
|
||||||
|
* bucket number and its hash bucket.
|
||||||
|
*/
|
||||||
|
static inline uint32
|
||||||
|
hash_initial_lookup(HTAB *hashp, uint32 hashvalue, HASHBUCKET **bucketptr)
|
||||||
|
{
|
||||||
|
HASHHDR *hctl = hashp->hctl;
|
||||||
|
HASHSEGMENT segp;
|
||||||
|
long segment_num;
|
||||||
|
long segment_ndx;
|
||||||
|
uint32 bucket;
|
||||||
|
|
||||||
|
bucket = calc_bucket(hctl, hashvalue);
|
||||||
|
|
||||||
|
segment_num = bucket >> hashp->sshift;
|
||||||
|
segment_ndx = MOD(bucket, hashp->ssize);
|
||||||
|
|
||||||
|
segp = hashp->dir[segment_num];
|
||||||
|
|
||||||
|
if (segp == NULL)
|
||||||
|
hash_corrupted(hashp);
|
||||||
|
|
||||||
|
*bucketptr = &segp[segment_ndx];
|
||||||
|
return bucket;
|
||||||
|
}
|
||||||
|
|
||||||
/* complain when we have detected a corrupted hashtable */
|
/* complain when we have detected a corrupted hashtable */
|
||||||
static void
|
static void
|
||||||
hash_corrupted(HTAB *hashp)
|
hash_corrupted(HTAB *hashp)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user