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

Commit40af10b

Browse files
committed
Use Generation memory contexts to store tuples in sorts
The general usage pattern when we store tuples in tuplesort.c is thatwe store a series of tuples one by one then either perform a sort or spillthem to disk. In the common case, there is no pfreeing of already storedtuples. For the common case since we do not individually pfree tuples, wehave very little need for aset.c memory allocation behavior whichmaintains freelists and always rounds allocation sizes up to the nextpower of 2 size.Here we conditionally use generation.c contexts for storing tuples intuplesort.c when the sort will never be bounded. Unfortunately, thememory context to store tuples is already created by the time any callswould be made to tuplesort_set_bound(), so here we add a new sort optionthat allows callers to specify if they're going to need a bounded sort ornot. We'll use a standard aset.c allocator when this sort option is notset.Extension authors must ensure that the TUPLESORT_ALLOWBOUNDED flag isused when calling tuplesort_begin_* for any sorts that make a call totuplesort_set_bound().Author: David RowleyReviewed-by: Andy FanDiscussion:https://postgr.es/m/CAApHDvoH4ASzsAOyHcxkuY01Qf++8JJ0paw+03dk+W25tQEcNQ@mail.gmail.com
1 parent77bae39 commit40af10b

File tree

4 files changed

+24
-5
lines changed

4 files changed

+24
-5
lines changed

‎src/backend/executor/nodeIncrementalSort.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ switchToPresortedPrefixMode(PlanState *pstate)
315315
&(plannode->sort.nullsFirst[nPresortedCols]),
316316
work_mem,
317317
NULL,
318-
TUPLESORT_NONE);
318+
node->bounded ?TUPLESORT_ALLOWBOUNDED :TUPLESORT_NONE);
319319
node->prefixsort_state=prefixsort_state;
320320
}
321321
else
@@ -616,6 +616,8 @@ ExecIncrementalSort(PlanState *pstate)
616616
plannode->sort.nullsFirst,
617617
work_mem,
618618
NULL,
619+
node->bounded ?
620+
TUPLESORT_ALLOWBOUNDED :
619621
TUPLESORT_NONE);
620622
node->fullsort_state=fullsort_state;
621623
}

‎src/backend/executor/nodeSort.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ ExecSort(PlanState *pstate)
9999

100100
if (node->randomAccess)
101101
tuplesortopts |=TUPLESORT_RANDOMACCESS;
102+
if (node->bounded)
103+
tuplesortopts |=TUPLESORT_ALLOWBOUNDED;
102104

103105
if (node->datumSort)
104106
tuplesortstate=tuplesort_begin_datum(TupleDescAttr(tupDesc,0)->atttypid,

‎src/backend/utils/sort/tuplesort.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -935,11 +935,21 @@ tuplesort_begin_batch(Tuplesortstate *state)
935935
* eases memory management. Resetting at key points reduces
936936
* fragmentation. Note that the memtuples array of SortTuples is allocated
937937
* in the parent context, not this context, because there is no need to
938-
* free memtuples early.
938+
* free memtuples early. For bounded sorts, tuples may be pfreed in any
939+
* order, so we use a regular aset.c context so that it can make use of
940+
* free'd memory. When the sort is not bounded, we make use of a
941+
* generation.c context as this keeps allocations more compact with less
942+
* wastage. Allocations are also slightly more CPU efficient.
939943
*/
940-
state->tuplecontext=AllocSetContextCreate(state->sortcontext,
941-
"Caller tuples",
942-
ALLOCSET_DEFAULT_SIZES);
944+
if (state->sortopt&TUPLESORT_ALLOWBOUNDED)
945+
state->tuplecontext=AllocSetContextCreate(state->sortcontext,
946+
"Caller tuples",
947+
ALLOCSET_DEFAULT_SIZES);
948+
else
949+
state->tuplecontext=GenerationContextCreate(state->sortcontext,
950+
"Caller tuples",
951+
ALLOCSET_DEFAULT_SIZES);
952+
943953

944954
state->status=TSS_INITIAL;
945955
state->bounded= false;
@@ -1444,6 +1454,8 @@ tuplesort_set_bound(Tuplesortstate *state, int64 bound)
14441454
{
14451455
/* Assert we're called before loading any tuples */
14461456
Assert(state->status==TSS_INITIAL&&state->memtupcount==0);
1457+
/* Assert we allow bounded sorts */
1458+
Assert(state->sortopt&TUPLESORT_ALLOWBOUNDED);
14471459
/* Can't set the bound twice, either */
14481460
Assert(!state->bounded);
14491461
/* Also, this shouldn't be called in a parallel worker */

‎src/include/utils/tuplesort.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ typedef enum
9292
/* specifies whether non-sequential access to the sort result is required */
9393
#defineTUPLESORT_RANDOMACCESS(1 << 0)
9494

95+
/* specifies if the tuplesort is able to support bounded sorts */
96+
#defineTUPLESORT_ALLOWBOUNDED(1 << 1)
97+
9598
typedefstructTuplesortInstrumentation
9699
{
97100
TuplesortMethodsortMethod;/* sort algorithm used */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp