@ -20,6 +20,13 @@
# include "miscadmin.h"
# include "miscadmin.h"
# include "utils/lsyscache.h"
# include "utils/lsyscache.h"
typedef struct TupleHashEntryData
{
MinimalTuple firstTuple ; /* copy of first tuple in this group */
uint32 status ; /* hash status */
uint32 hash ; /* hash value (cached) */
} TupleHashEntryData ;
static int TupleHashTableMatch ( struct tuplehash_hash * tb , const MinimalTuple tuple1 , const MinimalTuple tuple2 ) ;
static int TupleHashTableMatch ( struct tuplehash_hash * tb , const MinimalTuple tuple1 , const MinimalTuple tuple2 ) ;
static inline uint32 TupleHashTableHash_internal ( struct tuplehash_hash * tb ,
static inline uint32 TupleHashTableHash_internal ( struct tuplehash_hash * tb ,
const MinimalTuple tuple ) ;
const MinimalTuple tuple ) ;
@ -196,6 +203,7 @@ BuildTupleHashTable(PlanState *parent,
hashtable - > tab_collations = collations ;
hashtable - > tab_collations = collations ;
hashtable - > tablecxt = tablecxt ;
hashtable - > tablecxt = tablecxt ;
hashtable - > tempcxt = tempcxt ;
hashtable - > tempcxt = tempcxt ;
hashtable - > additionalsize = additionalsize ;
hashtable - > tableslot = NULL ; /* will be made on first lookup */
hashtable - > tableslot = NULL ; /* will be made on first lookup */
hashtable - > inputslot = NULL ;
hashtable - > inputslot = NULL ;
hashtable - > in_hash_expr = NULL ;
hashtable - > in_hash_expr = NULL ;
@ -273,6 +281,15 @@ ResetTupleHashTable(TupleHashTable hashtable)
tuplehash_reset ( hashtable - > hashtab ) ;
tuplehash_reset ( hashtable - > hashtab ) ;
}
}
/*
* Return size of the hash bucket . Useful for estimating memory usage .
*/
size_t
TupleHashEntrySize ( void )
{
return sizeof ( TupleHashEntryData ) ;
}
/*
/*
* Find or create a hashtable entry for the tuple group containing the
* Find or create a hashtable entry for the tuple group containing the
* given tuple . The tuple must be the same type as the hashtable entries .
* given tuple . The tuple must be the same type as the hashtable entries .
@ -339,6 +356,24 @@ TupleHashTableHash(TupleHashTable hashtable, TupleTableSlot *slot)
return hash ;
return hash ;
}
}
MinimalTuple
TupleHashEntryGetTuple ( TupleHashEntry entry )
{
return entry - > firstTuple ;
}
/*
* Get a pointer into the additional space allocated for this entry . The
* amount of space available is the additionalsize specified to
* BuildTupleHashTable ( ) . If additionalsize was specified as zero , no
* additional space is available and this function should not be called .
*/
void *
TupleHashEntryGetAdditional ( TupleHashEntry entry )
{
return ( char * ) entry - > firstTuple + MAXALIGN ( entry - > firstTuple - > t_len ) ;
}
/*
/*
* A variant of LookupTupleHashEntry for callers that have already computed
* A variant of LookupTupleHashEntry for callers that have already computed
* the hash value .
* the hash value .
@ -477,13 +512,31 @@ LookupTupleHashEntry_internal(TupleHashTable hashtable, TupleTableSlot *slot,
}
}
else
else
{
{
MinimalTuple firstTuple ;
size_t totalsize ; /* including alignment and additionalsize */
/* created new entry */
/* created new entry */
* isnew = true ;
* isnew = true ;
/* zero caller data */
/* zero caller data */
entry - > additional = NULL ;
MemoryContextSwitchTo ( hashtable - > tablecxt ) ;
MemoryContextSwitchTo ( hashtable - > tablecxt ) ;
/* Copy the first tuple into the table context */
/* Copy the first tuple into the table context */
entry - > firstTuple = ExecCopySlotMinimalTuple ( slot ) ;
firstTuple = ExecCopySlotMinimalTuple ( slot ) ;
/*
* Allocate additional space right after the MinimalTuple of size
* additionalsize . The caller can get a pointer to this data with
* TupleHashEntryGetAdditional ( ) , and store arbitrary data there .
*
* This avoids the need to store an extra pointer or allocate an
* additional chunk , which would waste memory .
*/
totalsize = MAXALIGN ( firstTuple - > t_len ) + hashtable - > additionalsize ;
firstTuple = repalloc ( firstTuple , totalsize ) ;
memset ( ( char * ) firstTuple + firstTuple - > t_len , 0 ,
totalsize - firstTuple - > t_len ) ;
entry - > firstTuple = firstTuple ;
}
}
}
}
else
else