2525#include "utils/lsyscache.h"
2626#include "utils/memutils.h"
2727
28- static uint32 TupleHashTableHash (struct tuplehash_hash * tb , const MinimalTuple tuple );
2928static 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 );
3031
3132/*
3233 * Define parameters for tuple hash table code generation. The interface is
@@ -300,10 +301,9 @@ TupleHashEntry
300301LookupTupleHashEntry (TupleHashTable hashtable , TupleTableSlot * slot ,
301302 bool * isnew )
302303{
303- TupleHashEntryData * entry ;
304- MemoryContext oldContext ;
305- bool found ;
306- MinimalTuple key ;
304+ TupleHashEntry entry ;
305+ MemoryContext oldContext ;
306+ uint32 hash ;
307307
308308 /* Need to run the hash functions in short-lived context */
309309 oldContext = MemoryContextSwitchTo (hashtable -> tempcxt );
@@ -313,32 +313,34 @@ LookupTupleHashEntry(TupleHashTable hashtable, TupleTableSlot *slot,
313313 hashtable -> in_hash_funcs = hashtable -> tab_hash_funcs ;
314314 hashtable -> cur_eq_func = hashtable -> tab_eq_func ;
315315
316- key = NULL ; /* flag to reference inputslot */
316+ hash = TupleHashTableHash (hashtable -> hashtab , NULL );
317+ entry = LookupTupleHashEntry_internal (hashtable , slot , isnew , hash );
317318
318- if (isnew )
319- {
320- entry = tuplehash_insert (hashtable -> hashtab , key , & found );
319+ MemoryContextSwitchTo (oldContext );
321320
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 );
342344
343345 MemoryContextSwitchTo (oldContext );
344346
@@ -389,7 +391,7 @@ FindTupleHashEntry(TupleHashTable hashtable, TupleTableSlot *slot,
389391 * Also, the caller must select an appropriate memory context for running
390392 * the hash functions. (dynahash.c doesn't change CurrentMemoryContext.)
391393 */
392- static uint32
394+ uint32
393395TupleHashTableHash (struct tuplehash_hash * tb , const MinimalTuple tuple )
394396{
395397 TupleHashTable hashtable = (TupleHashTable ) tb -> private_data ;
@@ -450,6 +452,52 @@ TupleHashTableHash(struct tuplehash_hash *tb, const MinimalTuple tuple)
450452 return murmurhash32 (hashkey );
451453}
452454
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+
453501/*
454502 * See whether two tuples (presumably of the same hash value) match
455503 */
0 commit comments