Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5b618e1

Browse files
committed
Minor refactor of nodeAgg.c.
* Separate calculation of hash value from the lookup. * Split build_hash_table() into two functions. * Change lookup_hash_entry() to return AggStatePerGroup. That's all the caller needed, anyway.These changes are to support the upcoming Disk-based Hash Aggregationwork.Discussion:https://postgr.es/m/31f5ab871a3ad5a1a91a7a797651f20e77ac7ce3.camel%40j-davis.com
1 parent8021985 commit5b618e1

File tree

1 file changed

+89
-51
lines changed

1 file changed

+89
-51
lines changed

‎src/backend/executor/nodeAgg.c

Lines changed: 89 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ static void finalize_partialaggregate(AggState *aggstate,
263263
AggStatePerAggperagg,
264264
AggStatePerGrouppergroupstate,
265265
Datum*resultVal,bool*resultIsNull);
266+
staticvoidprepare_hash_slot(AggState*aggstate);
266267
staticvoidprepare_projection_slot(AggState*aggstate,
267268
TupleTableSlot*slot,
268269
intcurrentSet);
@@ -272,8 +273,9 @@ static void finalize_aggregates(AggState *aggstate,
272273
staticTupleTableSlot*project_aggregates(AggState*aggstate);
273274
staticBitmapset*find_unaggregated_cols(AggState*aggstate);
274275
staticboolfind_unaggregated_cols_walker(Node*node,Bitmapset**colnos);
275-
staticvoidbuild_hash_table(AggState*aggstate);
276-
staticTupleHashEntryData*lookup_hash_entry(AggState*aggstate);
276+
staticvoidbuild_hash_tables(AggState*aggstate);
277+
staticvoidbuild_hash_table(AggState*aggstate,intsetno,longnbuckets);
278+
staticAggStatePerGrouplookup_hash_entry(AggState*aggstate,uint32hash);
277279
staticvoidlookup_hash_entries(AggState*aggstate);
278280
staticTupleTableSlot*agg_retrieve_direct(AggState*aggstate);
279281
staticvoidagg_fill_hash_table(AggState*aggstate);
@@ -1035,6 +1037,32 @@ finalize_partialaggregate(AggState *aggstate,
10351037
MemoryContextSwitchTo(oldContext);
10361038
}
10371039

1040+
/*
1041+
* Extract the attributes that make up the grouping key into the
1042+
* hashslot. This is necessary to compute the hash or perform a lookup.
1043+
*/
1044+
staticvoid
1045+
prepare_hash_slot(AggState*aggstate)
1046+
{
1047+
TupleTableSlot*inputslot=aggstate->tmpcontext->ecxt_outertuple;
1048+
AggStatePerHashperhash=&aggstate->perhash[aggstate->current_set];
1049+
TupleTableSlot*hashslot=perhash->hashslot;
1050+
inti;
1051+
1052+
/* transfer just the needed columns into hashslot */
1053+
slot_getsomeattrs(inputslot,perhash->largestGrpColIdx);
1054+
ExecClearTuple(hashslot);
1055+
1056+
for (i=0;i<perhash->numhashGrpCols;i++)
1057+
{
1058+
intvarNumber=perhash->hashGrpColIdxInput[i]-1;
1059+
1060+
hashslot->tts_values[i]=inputslot->tts_values[varNumber];
1061+
hashslot->tts_isnull[i]=inputslot->tts_isnull[varNumber];
1062+
}
1063+
ExecStoreVirtualTuple(hashslot);
1064+
}
1065+
10381066
/*
10391067
* Prepare to finalize and project based on the specified representative tuple
10401068
* slot and grouping set.
@@ -1249,41 +1277,59 @@ find_unaggregated_cols_walker(Node *node, Bitmapset **colnos)
12491277
* they are all reset at the same time).
12501278
*/
12511279
staticvoid
1252-
build_hash_table(AggState*aggstate)
1280+
build_hash_tables(AggState*aggstate)
12531281
{
1254-
MemoryContexttmpmem=aggstate->tmpcontext->ecxt_per_tuple_memory;
1255-
Sizeadditionalsize;
1256-
inti;
1282+
intsetno;
12571283

1258-
Assert(aggstate->aggstrategy==AGG_HASHED||aggstate->aggstrategy==AGG_MIXED);
1259-
1260-
additionalsize=aggstate->numtrans*sizeof(AggStatePerGroupData);
1261-
1262-
for (i=0;i<aggstate->num_hashes;++i)
1284+
for (setno=0;setno<aggstate->num_hashes;++setno)
12631285
{
1264-
AggStatePerHashperhash=&aggstate->perhash[i];
1286+
AggStatePerHashperhash=&aggstate->perhash[setno];
12651287

12661288
Assert(perhash->aggnode->numGroups>0);
12671289

1268-
if (perhash->hashtable)
1269-
ResetTupleHashTable(perhash->hashtable);
1270-
else
1271-
perhash->hashtable=BuildTupleHashTableExt(&aggstate->ss.ps,
1272-
perhash->hashslot->tts_tupleDescriptor,
1273-
perhash->numCols,
1274-
perhash->hashGrpColIdxHash,
1275-
perhash->eqfuncoids,
1276-
perhash->hashfunctions,
1277-
perhash->aggnode->grpCollations,
1278-
perhash->aggnode->numGroups,
1279-
additionalsize,
1280-
aggstate->ss.ps.state->es_query_cxt,
1281-
aggstate->hashcontext->ecxt_per_tuple_memory,
1282-
tmpmem,
1283-
DO_AGGSPLIT_SKIPFINAL(aggstate->aggsplit));
1290+
build_hash_table(aggstate,setno,perhash->aggnode->numGroups);
12841291
}
12851292
}
12861293

1294+
/*
1295+
* Build a single hashtable for this grouping set.
1296+
*/
1297+
staticvoid
1298+
build_hash_table(AggState*aggstate,intsetno,longnbuckets)
1299+
{
1300+
AggStatePerHashperhash=&aggstate->perhash[setno];
1301+
MemoryContextmetacxt=aggstate->ss.ps.state->es_query_cxt;
1302+
MemoryContexthashcxt=aggstate->hashcontext->ecxt_per_tuple_memory;
1303+
MemoryContexttmpcxt=aggstate->tmpcontext->ecxt_per_tuple_memory;
1304+
Sizeadditionalsize;
1305+
1306+
Assert(aggstate->aggstrategy==AGG_HASHED||
1307+
aggstate->aggstrategy==AGG_MIXED);
1308+
1309+
/*
1310+
* Used to make sure initial hash table allocation does not exceed
1311+
* work_mem. Note that the estimate does not include space for
1312+
* pass-by-reference transition data values, nor for the representative
1313+
* tuple of each group.
1314+
*/
1315+
additionalsize=aggstate->numtrans*sizeof(AggStatePerGroupData);
1316+
1317+
perhash->hashtable=BuildTupleHashTableExt(
1318+
&aggstate->ss.ps,
1319+
perhash->hashslot->tts_tupleDescriptor,
1320+
perhash->numCols,
1321+
perhash->hashGrpColIdxHash,
1322+
perhash->eqfuncoids,
1323+
perhash->hashfunctions,
1324+
perhash->aggnode->grpCollations,
1325+
nbuckets,
1326+
additionalsize,
1327+
metacxt,
1328+
hashcxt,
1329+
tmpcxt,
1330+
DO_AGGSPLIT_SKIPFINAL(aggstate->aggsplit));
1331+
}
1332+
12871333
/*
12881334
* Compute columns that actually need to be stored in hashtable entries. The
12891335
* incoming tuples from the child plan node will contain grouping columns,
@@ -1441,33 +1487,20 @@ hash_agg_entry_size(int numAggs, Size tupleWidth, Size transitionSpace)
14411487
* set (which the caller must have selected - note that initialize_aggregate
14421488
* depends on this).
14431489
*
1444-
* When called, CurrentMemoryContext should be the per-query context.
1490+
* When called, CurrentMemoryContext should be the per-query context. The
1491+
* already-calculated hash value for the tuple must be specified.
14451492
*/
1446-
staticTupleHashEntryData*
1447-
lookup_hash_entry(AggState*aggstate)
1493+
staticAggStatePerGroup
1494+
lookup_hash_entry(AggState*aggstate,uint32hash)
14481495
{
1449-
TupleTableSlot*inputslot=aggstate->tmpcontext->ecxt_outertuple;
14501496
AggStatePerHashperhash=&aggstate->perhash[aggstate->current_set];
14511497
TupleTableSlot*hashslot=perhash->hashslot;
14521498
TupleHashEntryData*entry;
14531499
boolisnew;
1454-
inti;
1455-
1456-
/* transfer just the needed columns into hashslot */
1457-
slot_getsomeattrs(inputslot,perhash->largestGrpColIdx);
1458-
ExecClearTuple(hashslot);
1459-
1460-
for (i=0;i<perhash->numhashGrpCols;i++)
1461-
{
1462-
intvarNumber=perhash->hashGrpColIdxInput[i]-1;
1463-
1464-
hashslot->tts_values[i]=inputslot->tts_values[varNumber];
1465-
hashslot->tts_isnull[i]=inputslot->tts_isnull[varNumber];
1466-
}
1467-
ExecStoreVirtualTuple(hashslot);
14681500

14691501
/* find or create the hashtable entry using the filtered tuple */
1470-
entry=LookupTupleHashEntry(perhash->hashtable,hashslot,&isnew);
1502+
entry=LookupTupleHashEntryHash(perhash->hashtable,hashslot,&isnew,
1503+
hash);
14711504

14721505
if (isnew)
14731506
{
@@ -1492,7 +1525,7 @@ lookup_hash_entry(AggState *aggstate)
14921525
}
14931526
}
14941527

1495-
returnentry;
1528+
returnentry->additional;
14961529
}
14971530

14981531
/*
@@ -1510,8 +1543,13 @@ lookup_hash_entries(AggState *aggstate)
15101543

15111544
for (setno=0;setno<numHashes;setno++)
15121545
{
1546+
AggStatePerHashperhash=&aggstate->perhash[setno];
1547+
uint32hash;
1548+
15131549
select_current_set(aggstate,setno, true);
1514-
pergroup[setno]=lookup_hash_entry(aggstate)->additional;
1550+
prepare_hash_slot(aggstate);
1551+
hash=TupleHashTableHash(perhash->hashtable,perhash->hashslot);
1552+
pergroup[setno]=lookup_hash_entry(aggstate,hash);
15151553
}
15161554
}
15171555

@@ -2478,7 +2516,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
24782516
aggstate->hash_pergroup=pergroups;
24792517

24802518
find_hash_columns(aggstate);
2481-
build_hash_table(aggstate);
2519+
build_hash_tables(aggstate);
24822520
aggstate->table_filled= false;
24832521
}
24842522

@@ -3498,7 +3536,7 @@ ExecReScanAgg(AggState *node)
34983536
{
34993537
ReScanExprContext(node->hashcontext);
35003538
/* Rebuild an empty hash table */
3501-
build_hash_table(node);
3539+
build_hash_tables(node);
35023540
node->table_filled= false;
35033541
/* iterator will be reset when the table is filled */
35043542
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp