Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 097366c

Browse files
committed
Move memory management away from writetup() and tuplesort_put*()
This commit puts some generic work away from sort-variant-specific function. In particular, tuplesort_put*() now doesn't need to decrease available memory and switch to sort context before calling puttuple_common(). writetup() doesn't need to free SortTuple.tuple and increase available memory. Discussion: https://postgr.es/m/CAPpHfdvjix0Ahx-H3Jp1M2R%2B_74P-zKnGGygx4OWr%3DbUQ8BNdw%40mail.gmail.com Author: Alexander Korotkov Reviewed-by: Pavel Borisov, Maxim Orlov, Matthias van de Meent Reviewed-by: Andres Freund, John Naylor
1 parent 033dd02 commit 097366c

File tree

1 file changed

+33
-45
lines changed

1 file changed

+33
-45
lines changed

src/backend/utils/sort/tuplesort.c

+33-45
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,7 @@ struct Tuplesortstate
288288

289289
/*
290290
* Function to write a stored tuple onto tape. The representation of the
291-
* tuple on tape need not be the same as it is in memory; requirements on
292-
* the tape representation are given below. Unless the slab allocator is
293-
* used, after writing the tuple, pfree() the out-of-line data (not the
294-
* SortTuple struct!), and increase state->availMem by the amount of
295-
* memory space thereby released.
291+
* tuple on tape need not be the same as it is in memory.
296292
*/
297293
void (*writetup) (Tuplesortstate *state, LogicalTape *tape,
298294
SortTuple *stup);
@@ -549,7 +545,7 @@ struct Sharedsort
549545

550546
#define REMOVEABBREV(state,stup,count) ((*(state)->removeabbrev) (state, stup, count))
551547
#define COMPARETUP(state,a,b) ((*(state)->comparetup) (a, b, state))
552-
#define WRITETUP(state,tape,stup) ((*(state)->writetup) (state, tape, stup))
548+
#define WRITETUP(state,tape,stup) (writetuple(state, tape, stup))
553549
#define READTUP(state,stup,tape,len) ((*(state)->readtup) (state, stup, tape, len))
554550
#define LACKMEM(state) ((state)->availMem < 0 && !(state)->slabAllocatorUsed)
555551
#define USEMEM(state,amt) ((state)->availMem -= (amt))
@@ -618,6 +614,8 @@ static Tuplesortstate *tuplesort_begin_common(int workMem,
618614
static void tuplesort_begin_batch(Tuplesortstate *state);
619615
static void puttuple_common(Tuplesortstate *state, SortTuple *tuple,
620616
bool useAbbrev);
617+
static void writetuple(Tuplesortstate *state, LogicalTape *tape,
618+
SortTuple *stup);
621619
static bool consider_abort_common(Tuplesortstate *state);
622620
static void inittapes(Tuplesortstate *state, bool mergeruns);
623621
static void inittapestate(Tuplesortstate *state, int maxTapes);
@@ -1848,7 +1846,6 @@ tuplesort_puttupleslot(Tuplesortstate *state, TupleTableSlot *slot)
18481846
/* copy the tuple into sort storage */
18491847
tuple = ExecCopySlotMinimalTuple(slot);
18501848
stup.tuple = (void *) tuple;
1851-
USEMEM(state, GetMemoryChunkSpace(tuple));
18521849
/* set up first-column key value */
18531850
htup.t_len = tuple->t_len + MINIMAL_TUPLE_OFFSET;
18541851
htup.t_data = (HeapTupleHeader) ((char *) tuple - MINIMAL_TUPLE_OFFSET);
@@ -1857,8 +1854,6 @@ tuplesort_puttupleslot(Tuplesortstate *state, TupleTableSlot *slot)
18571854
state->tupDesc,
18581855
&stup.isnull1);
18591856

1860-
MemoryContextSwitchTo(state->sortcontext);
1861-
18621857
puttuple_common(state, &stup,
18631858
state->sortKeys->abbrev_converter && !stup.isnull1);
18641859

@@ -1879,9 +1874,6 @@ tuplesort_putheaptuple(Tuplesortstate *state, HeapTuple tup)
18791874
/* copy the tuple into sort storage */
18801875
tup = heap_copytuple(tup);
18811876
stup.tuple = (void *) tup;
1882-
USEMEM(state, GetMemoryChunkSpace(tup));
1883-
1884-
MemoryContextSwitchTo(state->sortcontext);
18851877

18861878
/*
18871879
* set up first-column key value, and potentially abbreviate, if it's a
@@ -1910,27 +1902,21 @@ tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel,
19101902
ItemPointer self, Datum *values,
19111903
bool *isnull)
19121904
{
1913-
MemoryContext oldcontext;
19141905
SortTuple stup;
19151906
IndexTuple tuple;
19161907

19171908
stup.tuple = index_form_tuple_context(RelationGetDescr(rel), values,
19181909
isnull, state->tuplecontext);
19191910
tuple = ((IndexTuple) stup.tuple);
19201911
tuple->t_tid = *self;
1921-
USEMEM(state, GetMemoryChunkSpace(stup.tuple));
19221912
/* set up first-column key value */
19231913
stup.datum1 = index_getattr(tuple,
19241914
1,
19251915
RelationGetDescr(state->indexRel),
19261916
&stup.isnull1);
19271917

1928-
oldcontext = MemoryContextSwitchTo(state->sortcontext);
1929-
19301918
puttuple_common(state, &stup,
19311919
state->sortKeys && state->sortKeys->abbrev_converter && !stup.isnull1);
1932-
1933-
MemoryContextSwitchTo(oldcontext);
19341920
}
19351921

19361922
/*
@@ -1965,15 +1951,12 @@ tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull)
19651951
stup.datum1 = !isNull ? val : (Datum) 0;
19661952
stup.isnull1 = isNull;
19671953
stup.tuple = NULL; /* no separate storage */
1968-
MemoryContextSwitchTo(state->sortcontext);
19691954
}
19701955
else
19711956
{
19721957
stup.isnull1 = false;
19731958
stup.datum1 = datumCopy(val, false, state->datumTypeLen);
19741959
stup.tuple = DatumGetPointer(stup.datum1);
1975-
USEMEM(state, GetMemoryChunkSpace(stup.tuple));
1976-
MemoryContextSwitchTo(state->sortcontext);
19771960
}
19781961

19791962
puttuple_common(state, &stup,
@@ -1988,8 +1971,14 @@ tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull)
19881971
static void
19891972
puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbrev)
19901973
{
1974+
MemoryContext oldcontext = MemoryContextSwitchTo(state->sortcontext);
1975+
19911976
Assert(!LEADER(state));
19921977

1978+
/* Count the size of the out-of-line data */
1979+
if (tuple->tuple != NULL)
1980+
USEMEM(state, GetMemoryChunkSpace(tuple->tuple));
1981+
19931982
if (!useAbbrev)
19941983
{
19951984
/*
@@ -2062,14 +2051,18 @@ puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbrev)
20622051
pg_rusage_show(&state->ru_start));
20632052
#endif
20642053
make_bounded_heap(state);
2054+
MemoryContextSwitchTo(oldcontext);
20652055
return;
20662056
}
20672057

20682058
/*
20692059
* Done if we still fit in available memory and have array slots.
20702060
*/
20712061
if (state->memtupcount < state->memtupsize && !LACKMEM(state))
2062+
{
2063+
MemoryContextSwitchTo(oldcontext);
20722064
return;
2065+
}
20732066

20742067
/*
20752068
* Nope; time to switch to tape-based operation.
@@ -2123,6 +2116,25 @@ puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbrev)
21232116
elog(ERROR, "invalid tuplesort state");
21242117
break;
21252118
}
2119+
MemoryContextSwitchTo(oldcontext);
2120+
}
2121+
2122+
/*
2123+
* Write a stored tuple onto tape.tuple. Unless the slab allocator is
2124+
* used, after writing the tuple, pfree() the out-of-line data (not the
2125+
* SortTuple struct!), and increase state->availMem by the amount of
2126+
* memory space thereby released.
2127+
*/
2128+
static void
2129+
writetuple(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
2130+
{
2131+
state->writetup(state, tape, stup);
2132+
2133+
if (!state->slabAllocatorUsed && stup->tuple)
2134+
{
2135+
FREEMEM(state, GetMemoryChunkSpace(stup->tuple));
2136+
pfree(stup->tuple);
2137+
}
21262138
}
21272139

21282140
static bool
@@ -3960,12 +3972,6 @@ writetup_heap(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
39603972
if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
39613973
* word? */
39623974
LogicalTapeWrite(tape, (void *) &tuplen, sizeof(tuplen));
3963-
3964-
if (!state->slabAllocatorUsed)
3965-
{
3966-
FREEMEM(state, GetMemoryChunkSpace(tuple));
3967-
heap_free_minimal_tuple(tuple);
3968-
}
39693975
}
39703976

39713977
static void
@@ -4141,12 +4147,6 @@ writetup_cluster(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
41414147
if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
41424148
* word? */
41434149
LogicalTapeWrite(tape, &tuplen, sizeof(tuplen));
4144-
4145-
if (!state->slabAllocatorUsed)
4146-
{
4147-
FREEMEM(state, GetMemoryChunkSpace(tuple));
4148-
heap_freetuple(tuple);
4149-
}
41504150
}
41514151

41524152
static void
@@ -4403,12 +4403,6 @@ writetup_index(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
44034403
if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
44044404
* word? */
44054405
LogicalTapeWrite(tape, (void *) &tuplen, sizeof(tuplen));
4406-
4407-
if (!state->slabAllocatorUsed)
4408-
{
4409-
FREEMEM(state, GetMemoryChunkSpace(tuple));
4410-
pfree(tuple);
4411-
}
44124406
}
44134407

44144408
static void
@@ -4495,12 +4489,6 @@ writetup_datum(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup)
44954489
if (state->sortopt & TUPLESORT_RANDOMACCESS) /* need trailing length
44964490
* word? */
44974491
LogicalTapeWrite(tape, (void *) &writtenlen, sizeof(writtenlen));
4498-
4499-
if (!state->slabAllocatorUsed && stup->tuple)
4500-
{
4501-
FREEMEM(state, GetMemoryChunkSpace(stup->tuple));
4502-
pfree(stup->tuple);
4503-
}
45044492
}
45054493

45064494
static void

0 commit comments

Comments
 (0)