Skip to content

Commit d0f0200

Browse files
committed
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
1 parent 3ab2668 commit d0f0200

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

src/backend/utils/hash/dynahash.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,10 +1387,30 @@ hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
13871387
status->hashp = hashp;
13881388
status->curBucket = 0;
13891389
status->curEntry = NULL;
1390+
status->hasHashvalue = false;
13901391
if (!hashp->frozen)
13911392
register_seq_scan(hashp);
13921393
}
13931394

1395+
/*
1396+
* Same as above but scan by the given hash value.
1397+
* See also hash_seq_search().
1398+
*/
1399+
void
1400+
hash_seq_init_with_hash_value(HASH_SEQ_STATUS *status, HTAB *hashp,
1401+
uint32 hashvalue)
1402+
{
1403+
HASHBUCKET *bucketPtr;
1404+
1405+
hash_seq_init(status, hashp);
1406+
1407+
status->hasHashvalue = true;
1408+
status->hashvalue = hashvalue;
1409+
1410+
status->curBucket = hash_initial_lookup(hashp, hashvalue, &bucketPtr);
1411+
status->curEntry = *bucketPtr;
1412+
}
1413+
13941414
void *
13951415
hash_seq_search(HASH_SEQ_STATUS *status)
13961416
{
@@ -1404,6 +1424,24 @@ hash_seq_search(HASH_SEQ_STATUS *status)
14041424
uint32 curBucket;
14051425
HASHELEMENT *curElem;
14061426

1427+
if (status->hasHashvalue)
1428+
{
1429+
/*
1430+
* Scan entries only in the current bucket because only this bucket
1431+
* can contain entries with the given hash value.
1432+
*/
1433+
while ((curElem = status->curEntry) != NULL)
1434+
{
1435+
status->curEntry = curElem->link;
1436+
if (status->hashvalue != curElem->hashvalue)
1437+
continue;
1438+
return (void *) ELEMENTKEY(curElem);
1439+
}
1440+
1441+
hash_seq_term(status);
1442+
return NULL;
1443+
}
1444+
14071445
if ((curElem = status->curEntry) != NULL)
14081446
{
14091447
/* Continuing scan of curBucket... */

src/include/utils/hsearch.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ typedef struct
122122
HTAB *hashp;
123123
uint32 curBucket; /* index of current bucket */
124124
HASHELEMENT *curEntry; /* current entry in bucket */
125+
bool hasHashvalue; /* true if hashvalue was provided */
126+
uint32 hashvalue; /* hashvalue to start seqscan over hash */
125127
} HASH_SEQ_STATUS;
126128

127129
/*
@@ -141,6 +143,9 @@ extern bool hash_update_hash_key(HTAB *hashp, void *existingEntry,
141143
const void *newKeyPtr);
142144
extern long hash_get_num_entries(HTAB *hashp);
143145
extern void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp);
146+
extern void hash_seq_init_with_hash_value(HASH_SEQ_STATUS *status,
147+
HTAB *hashp,
148+
uint32 hashvalue);
144149
extern void *hash_seq_search(HASH_SEQ_STATUS *status);
145150
extern void hash_seq_term(HASH_SEQ_STATUS *status);
146151
extern void hash_freeze(HTAB *hashp);

0 commit comments

Comments
 (0)