Skip to content
Snippets Groups Projects
Commit 2689abf0 authored by Tom Lane's avatar Tom Lane
Browse files

Incorporate a couple of recent tuplesort.c improvements into tuplestore.c.

In particular, ensure that enlargement of the memtuples[] array doesn't
fall foul of MaxAllocSize when work_mem is very large, and don't bother
enlarging it if that would force an immediate switch into 'tape' mode anyway.
parent 20bdc713
No related branches found
No related tags found
No related merge requests found
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/sort/tuplestore.c,v 1.25 2005/11/22 18:17:27 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/sort/tuplestore.c,v 1.26 2006/03/04 19:30:12 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -316,15 +316,28 @@ tuplestore_puttuple(Tuplestorestate *state, void *tuple) ...@@ -316,15 +316,28 @@ tuplestore_puttuple(Tuplestorestate *state, void *tuple)
switch (state->status) switch (state->status)
{ {
case TSS_INMEM: case TSS_INMEM:
/* Grow the array as needed */ /*
if (state->memtupcount >= state->memtupsize) * Grow the array as needed. Note that we try to grow the array
* when there is still one free slot remaining --- if we fail,
* there'll still be room to store the incoming tuple, and then
* we'll switch to tape-based operation.
*/
if (state->memtupcount >= state->memtupsize - 1)
{ {
FREEMEM(state, GetMemoryChunkSpace(state->memtuples)); /*
state->memtupsize *= 2; * See grow_memtuples() in tuplesort.c for the rationale
state->memtuples = (void **) * behind these two tests.
repalloc(state->memtuples, */
state->memtupsize * sizeof(void *)); if (state->availMem > (long) (state->memtupsize * sizeof(void *)) &&
USEMEM(state, GetMemoryChunkSpace(state->memtuples)); (Size) (state->memtupsize * 2) < MaxAllocSize / sizeof(void *))
{
FREEMEM(state, GetMemoryChunkSpace(state->memtuples));
state->memtupsize *= 2;
state->memtuples = (void **)
repalloc(state->memtuples,
state->memtupsize * sizeof(void *));
USEMEM(state, GetMemoryChunkSpace(state->memtuples));
}
} }
/* Stash the tuple in the in-memory array */ /* Stash the tuple in the in-memory array */
...@@ -335,9 +348,9 @@ tuplestore_puttuple(Tuplestorestate *state, void *tuple) ...@@ -335,9 +348,9 @@ tuplestore_puttuple(Tuplestorestate *state, void *tuple)
state->current = state->memtupcount; state->current = state->memtupcount;
/* /*
* Done if we still fit in available memory. * Done if we still fit in available memory and have array slots.
*/ */
if (!LACKMEM(state)) if (state->memtupcount < state->memtupsize && !LACKMEM(state))
return; return;
/* /*
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment