Skip to content

Commit 4eaea3d

Browse files
committed
Introduce TupleHashTableHash() and LookupTupleHashEntryHash().
Expose two new entry points: one for only calculating the hash value of a tuple, and another for looking up a hash entry when the hash value is already known. This will be useful for disk-based Hash Aggregation to avoid recomputing the hash value for the same tuple after saving and restoring it from disk. Discussion: https://postgr.es/m/37091115219dd522fd9ed67333ee8ed1b7e09443.camel%40j-davis.com
1 parent e6f86f8 commit 4eaea3d

File tree

2 files changed

+83
-30
lines changed

2 files changed

+83
-30
lines changed

src/backend/executor/execGrouping.c

Lines changed: 78 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@
2525
#include "utils/lsyscache.h"
2626
#include "utils/memutils.h"
2727

28-
static uint32 TupleHashTableHash(struct tuplehash_hash *tb, const MinimalTuple tuple);
2928
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);
3031

3132
/*
3233
* Define parameters for tuple hash table code generation. The interface is
@@ -300,10 +301,9 @@ TupleHashEntry
300301
LookupTupleHashEntry(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
393395
TupleHashTableHash(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
*/

src/include/executor/executor.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ extern TupleHashTable BuildTupleHashTableExt(PlanState *parent,
140140
extern TupleHashEntry LookupTupleHashEntry(TupleHashTable hashtable,
141141
TupleTableSlot *slot,
142142
bool *isnew);
143+
extern uint32 TupleHashTableHash(struct tuplehash_hash *tb,
144+
const MinimalTuple tuple);
145+
extern TupleHashEntry LookupTupleHashEntryHash(TupleHashTable hashtable,
146+
TupleTableSlot *slot,
147+
bool *isnew, uint32 hash);
143148
extern TupleHashEntry FindTupleHashEntry(TupleHashTable hashtable,
144149
TupleTableSlot *slot,
145150
ExprState *eqcomp,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy