Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 6455c65

Browse files
committed
Allow to reset execGrouping.c style tuple hashtables.
This has the advantage that the comparator expression, the table's slot, etc do not have to be rebuilt. Additionally the simplehash.h hashtable within the tuple hashtable now keeps its previous size and doesn't need to be reallocated. That both reduces allocator overhead, and improves performance in cases where the input estimation was off by a significant factor. To avoid an API/ABI break, the new parameter is exposed via the new BuildTupleHashTableExt(), and BuildTupleHashTable() now is a wrapper around the former, that continues to allocate the table itself in the tablecxt. Using this fixes performance issues discovered in the two bugs referenced. This commit however has not converted the callers, that's done in a separate commit. Bug: #15592 #15486 Reported-By: Jakub Janeček, Dmitry Marakasov Author: Andres Freund Discussion: https://postgr.es/m/15486-05850f065da42931@postgresql.org https://postgr.es/m/20190114180423.ywhdg2iagzvh43we@alap3.anarazel.de Backpatch: 11, this is a prerequisite for other fixes
1 parent 350b0a4 commit 6455c65

File tree

2 files changed

+66
-14
lines changed

2 files changed

+66
-14
lines changed

src/backend/executor/execGrouping.c

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ execTuplesHashPrepare(int numCols,
138138
* hashfunctions: datatype-specific hashing functions to use
139139
* nbuckets: initial estimate of hashtable size
140140
* additionalsize: size of data stored in ->additional
141-
* tablecxt: memory context in which to store table and table entries
141+
* metacxt: memory context for long-lived allocation, but not per-entry data
142+
* tablecxt: memory context in which to store table entries
142143
* tempcxt: short-lived context for evaluation hash and comparison functions
143144
*
144145
* The function arrays may be made with execTuplesHashPrepare(). Note they
@@ -149,14 +150,16 @@ execTuplesHashPrepare(int numCols,
149150
* storage that will live as long as the hashtable does.
150151
*/
151152
TupleHashTable
152-
BuildTupleHashTable(PlanState *parent,
153-
TupleDesc inputDesc,
154-
int numCols, AttrNumber *keyColIdx,
155-
Oid *eqfuncoids,
156-
FmgrInfo *hashfunctions,
157-
long nbuckets, Size additionalsize,
158-
MemoryContext tablecxt, MemoryContext tempcxt,
159-
bool use_variable_hash_iv)
153+
BuildTupleHashTableExt(PlanState *parent,
154+
TupleDesc inputDesc,
155+
int numCols, AttrNumber *keyColIdx,
156+
Oid *eqfuncoids,
157+
FmgrInfo *hashfunctions,
158+
long nbuckets, Size additionalsize,
159+
MemoryContext metacxt,
160+
MemoryContext tablecxt,
161+
MemoryContext tempcxt,
162+
bool use_variable_hash_iv)
160163
{
161164
TupleHashTable hashtable;
162165
Size entrysize = sizeof(TupleHashEntryData) + additionalsize;
@@ -167,8 +170,9 @@ BuildTupleHashTable(PlanState *parent,
167170
/* Limit initial table size request to not more than work_mem */
168171
nbuckets = Min(nbuckets, (long) ((work_mem * 1024L) / entrysize));
169172

170-
hashtable = (TupleHashTable)
171-
MemoryContextAlloc(tablecxt, sizeof(TupleHashTableData));
173+
oldcontext = MemoryContextSwitchTo(metacxt);
174+
175+
hashtable = (TupleHashTable) palloc(sizeof(TupleHashTableData));
172176

173177
hashtable->numCols = numCols;
174178
hashtable->keyColIdx = keyColIdx;
@@ -194,9 +198,7 @@ BuildTupleHashTable(PlanState *parent,
194198
else
195199
hashtable->hash_iv = 0;
196200

197-
hashtable->hashtab = tuplehash_create(tablecxt, nbuckets, hashtable);
198-
199-
oldcontext = MemoryContextSwitchTo(hashtable->tablecxt);
201+
hashtable->hashtab = tuplehash_create(metacxt, nbuckets, hashtable);
200202

201203
/*
202204
* We copy the input tuple descriptor just for safety --- we assume all
@@ -223,6 +225,46 @@ BuildTupleHashTable(PlanState *parent,
223225
return hashtable;
224226
}
225227

228+
/*
229+
* BuildTupleHashTable is a backwards-compatibilty wrapper for
230+
* BuildTupleHashTableExt(), that allocates the hashtable's metadata in
231+
* tablecxt. Note that hashtables created this way cannot be reset leak-free
232+
* with ResetTupleHashTable().
233+
*/
234+
TupleHashTable
235+
BuildTupleHashTable(PlanState *parent,
236+
TupleDesc inputDesc,
237+
int numCols, AttrNumber *keyColIdx,
238+
Oid *eqfuncoids,
239+
FmgrInfo *hashfunctions,
240+
long nbuckets, Size additionalsize,
241+
MemoryContext tablecxt,
242+
MemoryContext tempcxt,
243+
bool use_variable_hash_iv)
244+
{
245+
return BuildTupleHashTableExt(parent,
246+
inputDesc,
247+
numCols, keyColIdx,
248+
eqfuncoids,
249+
hashfunctions,
250+
nbuckets, additionalsize,
251+
tablecxt,
252+
tablecxt,
253+
tempcxt,
254+
use_variable_hash_iv);
255+
}
256+
257+
/*
258+
* Reset contents of the hashtable to be empty, preserving all the non-content
259+
* state. Note that the tablecxt passed to BuildTupleHashTableExt() should
260+
* also be reset, otherwise there will be leaks.
261+
*/
262+
void
263+
ResetTupleHashTable(TupleHashTable hashtable)
264+
{
265+
tuplehash_reset(hashtable->hashtab);
266+
}
267+
226268
/*
227269
* Find or create a hashtable entry for the tuple group containing the
228270
* given tuple. The tuple must be the same type as the hashtable entries.

src/include/executor/executor.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,23 @@ extern TupleHashTable BuildTupleHashTable(PlanState *parent,
129129
long nbuckets, Size additionalsize,
130130
MemoryContext tablecxt,
131131
MemoryContext tempcxt, bool use_variable_hash_iv);
132+
extern TupleHashTable BuildTupleHashTableExt(PlanState *parent,
133+
TupleDesc inputDesc,
134+
int numCols, AttrNumber *keyColIdx,
135+
Oid *eqfuncoids,
136+
FmgrInfo *hashfunctions,
137+
long nbuckets, Size additionalsize,
138+
MemoryContext metacxt,
139+
MemoryContext tablecxt,
140+
MemoryContext tempcxt, bool use_variable_hash_iv);
132141
extern TupleHashEntry LookupTupleHashEntry(TupleHashTable hashtable,
133142
TupleTableSlot *slot,
134143
bool *isnew);
135144
extern TupleHashEntry FindTupleHashEntry(TupleHashTable hashtable,
136145
TupleTableSlot *slot,
137146
ExprState *eqcomp,
138147
FmgrInfo *hashfunctions);
148+
extern void ResetTupleHashTable(TupleHashTable hashtable);
139149

140150
/*
141151
* prototypes from functions in execJunk.c

0 commit comments

Comments
 (0)