25
25
#include "utils/lsyscache.h"
26
26
#include "utils/memutils.h"
27
27
28
- static uint32 TupleHashTableHash (struct tuplehash_hash * tb , const MinimalTuple tuple );
29
28
static int TupleHashTableMatch (struct tuplehash_hash * tb , const MinimalTuple tuple1 , const MinimalTuple tuple2 );
29
+ static TupleHashEntry LookupTupleHashEntry_internal (
30
+ TupleHashTable hashtable , TupleTableSlot * slot , bool * isnew , uint32 hash );
30
31
31
32
/*
32
33
* Define parameters for tuple hash table code generation. The interface is
@@ -300,10 +301,9 @@ TupleHashEntry
300
301
LookupTupleHashEntry (TupleHashTable hashtable , TupleTableSlot * slot ,
301
302
bool * isnew )
302
303
{
303
- TupleHashEntryData * entry ;
304
- MemoryContext oldContext ;
305
- bool found ;
306
- MinimalTuple key ;
304
+ TupleHashEntry entry ;
305
+ MemoryContext oldContext ;
306
+ uint32 hash ;
307
307
308
308
/* Need to run the hash functions in short-lived context */
309
309
oldContext = MemoryContextSwitchTo (hashtable -> tempcxt );
@@ -313,32 +313,34 @@ LookupTupleHashEntry(TupleHashTable hashtable, TupleTableSlot *slot,
313
313
hashtable -> in_hash_funcs = hashtable -> tab_hash_funcs ;
314
314
hashtable -> cur_eq_func = hashtable -> tab_eq_func ;
315
315
316
- key = NULL ; /* flag to reference inputslot */
316
+ hash = TupleHashTableHash (hashtable -> hashtab , NULL );
317
+ entry = LookupTupleHashEntry_internal (hashtable , slot , isnew , hash );
317
318
318
- if (isnew )
319
- {
320
- entry = tuplehash_insert (hashtable -> hashtab , key , & found );
319
+ MemoryContextSwitchTo (oldContext );
321
320
322
- if (found )
323
- {
324
- /* found pre-existing entry */
325
- * isnew = false;
326
- }
327
- else
328
- {
329
- /* created new entry */
330
- * isnew = true;
331
- /* zero caller data */
332
- entry -> additional = NULL ;
333
- MemoryContextSwitchTo (hashtable -> tablecxt );
334
- /* Copy the first tuple into the table context */
335
- entry -> firstTuple = ExecCopySlotMinimalTuple (slot );
336
- }
337
- }
338
- else
339
- {
340
- entry = tuplehash_lookup (hashtable -> hashtab , key );
341
- }
321
+ return entry ;
322
+ }
323
+
324
+ /*
325
+ * A variant of LookupTupleHashEntry for callers that have already computed
326
+ * the hash value.
327
+ */
328
+ TupleHashEntry
329
+ LookupTupleHashEntryHash (TupleHashTable hashtable , TupleTableSlot * slot ,
330
+ bool * isnew , uint32 hash )
331
+ {
332
+ TupleHashEntry entry ;
333
+ MemoryContext oldContext ;
334
+
335
+ /* Need to run the hash functions in short-lived context */
336
+ oldContext = MemoryContextSwitchTo (hashtable -> tempcxt );
337
+
338
+ /* set up data needed by hash and match functions */
339
+ hashtable -> inputslot = slot ;
340
+ hashtable -> in_hash_funcs = hashtable -> tab_hash_funcs ;
341
+ hashtable -> cur_eq_func = hashtable -> tab_eq_func ;
342
+
343
+ entry = LookupTupleHashEntry_internal (hashtable , slot , isnew , hash );
342
344
343
345
MemoryContextSwitchTo (oldContext );
344
346
@@ -389,7 +391,7 @@ FindTupleHashEntry(TupleHashTable hashtable, TupleTableSlot *slot,
389
391
* Also, the caller must select an appropriate memory context for running
390
392
* the hash functions. (dynahash.c doesn't change CurrentMemoryContext.)
391
393
*/
392
- static uint32
394
+ uint32
393
395
TupleHashTableHash (struct tuplehash_hash * tb , const MinimalTuple tuple )
394
396
{
395
397
TupleHashTable hashtable = (TupleHashTable ) tb -> private_data ;
@@ -450,6 +452,52 @@ TupleHashTableHash(struct tuplehash_hash *tb, const MinimalTuple tuple)
450
452
return murmurhash32 (hashkey );
451
453
}
452
454
455
+ /*
456
+ * Does the work of LookupTupleHashEntry and LookupTupleHashEntryHash. Useful
457
+ * so that we can avoid switching the memory context multiple times for
458
+ * LookupTupleHashEntry.
459
+ *
460
+ * NB: This function may or may not change the memory context. Caller is
461
+ * expected to change it back.
462
+ */
463
+ static TupleHashEntry
464
+ LookupTupleHashEntry_internal (TupleHashTable hashtable , TupleTableSlot * slot ,
465
+ bool * isnew , uint32 hash )
466
+ {
467
+ TupleHashEntryData * entry ;
468
+ bool found ;
469
+ MinimalTuple key ;
470
+
471
+ key = NULL ; /* flag to reference inputslot */
472
+
473
+ if (isnew )
474
+ {
475
+ entry = tuplehash_insert_hash (hashtable -> hashtab , key , hash , & found );
476
+
477
+ if (found )
478
+ {
479
+ /* found pre-existing entry */
480
+ * isnew = false;
481
+ }
482
+ else
483
+ {
484
+ /* created new entry */
485
+ * isnew = true;
486
+ /* zero caller data */
487
+ entry -> additional = NULL ;
488
+ MemoryContextSwitchTo (hashtable -> tablecxt );
489
+ /* Copy the first tuple into the table context */
490
+ entry -> firstTuple = ExecCopySlotMinimalTuple (slot );
491
+ }
492
+ }
493
+ else
494
+ {
495
+ entry = tuplehash_lookup_hash (hashtable -> hashtab , key , hash );
496
+ }
497
+
498
+ return entry ;
499
+ }
500
+
453
501
/*
454
502
* See whether two tuples (presumably of the same hash value) match
455
503
*/
0 commit comments