Introduce hash_search_with_hash_value() function
This new function iterates hash entries with given hash values. This function is designed to avoid full sequential hash search in the syscache invalidation callbacks. Discussion: https://postgr.es/m/5812a6e5-68ae-4d84-9d85-b443176966a1%40sigaev.ru Author: Teodor Sigaev Reviewed-by: Aleksander Alekseev, Tom Lane, Michael Paquier, Roman Zharkov Reviewed-by: Andrei Lepikhov
This commit is contained in:
parent
3ab2668d48
commit
d0f020037e
@ -1387,10 +1387,30 @@ hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
|
||||
status->hashp = hashp;
|
||||
status->curBucket = 0;
|
||||
status->curEntry = NULL;
|
||||
status->hasHashvalue = false;
|
||||
if (!hashp->frozen)
|
||||
register_seq_scan(hashp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Same as above but scan by the given hash value.
|
||||
* See also hash_seq_search().
|
||||
*/
|
||||
void
|
||||
hash_seq_init_with_hash_value(HASH_SEQ_STATUS *status, HTAB *hashp,
|
||||
uint32 hashvalue)
|
||||
{
|
||||
HASHBUCKET *bucketPtr;
|
||||
|
||||
hash_seq_init(status, hashp);
|
||||
|
||||
status->hasHashvalue = true;
|
||||
status->hashvalue = hashvalue;
|
||||
|
||||
status->curBucket = hash_initial_lookup(hashp, hashvalue, &bucketPtr);
|
||||
status->curEntry = *bucketPtr;
|
||||
}
|
||||
|
||||
void *
|
||||
hash_seq_search(HASH_SEQ_STATUS *status)
|
||||
{
|
||||
@ -1404,6 +1424,24 @@ hash_seq_search(HASH_SEQ_STATUS *status)
|
||||
uint32 curBucket;
|
||||
HASHELEMENT *curElem;
|
||||
|
||||
if (status->hasHashvalue)
|
||||
{
|
||||
/*
|
||||
* Scan entries only in the current bucket because only this bucket
|
||||
* can contain entries with the given hash value.
|
||||
*/
|
||||
while ((curElem = status->curEntry) != NULL)
|
||||
{
|
||||
status->curEntry = curElem->link;
|
||||
if (status->hashvalue != curElem->hashvalue)
|
||||
continue;
|
||||
return (void *) ELEMENTKEY(curElem);
|
||||
}
|
||||
|
||||
hash_seq_term(status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((curElem = status->curEntry) != NULL)
|
||||
{
|
||||
/* Continuing scan of curBucket... */
|
||||
|
@ -122,6 +122,8 @@ typedef struct
|
||||
HTAB *hashp;
|
||||
uint32 curBucket; /* index of current bucket */
|
||||
HASHELEMENT *curEntry; /* current entry in bucket */
|
||||
bool hasHashvalue; /* true if hashvalue was provided */
|
||||
uint32 hashvalue; /* hashvalue to start seqscan over hash */
|
||||
} HASH_SEQ_STATUS;
|
||||
|
||||
/*
|
||||
@ -141,6 +143,9 @@ extern bool hash_update_hash_key(HTAB *hashp, void *existingEntry,
|
||||
const void *newKeyPtr);
|
||||
extern long hash_get_num_entries(HTAB *hashp);
|
||||
extern void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp);
|
||||
extern void hash_seq_init_with_hash_value(HASH_SEQ_STATUS *status,
|
||||
HTAB *hashp,
|
||||
uint32 hashvalue);
|
||||
extern void *hash_seq_search(HASH_SEQ_STATUS *status);
|
||||
extern void hash_seq_term(HASH_SEQ_STATUS *status);
|
||||
extern void hash_freeze(HTAB *hashp);
|
||||
|
Loading…
x
Reference in New Issue
Block a user