Skip to content

Commit 2689abf

Browse files
committed
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.
1 parent 20bdc71 commit 2689abf

File tree

1 file changed

+24
-11
lines changed

1 file changed

+24
-11
lines changed

src/backend/utils/sort/tuplestore.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
* Portions Copyright (c) 1994, Regents of the University of California
3737
*
3838
* IDENTIFICATION
39-
* $PostgreSQL: pgsql/src/backend/utils/sort/tuplestore.c,v 1.25 2005/11/22 18:17:27 momjian Exp $
39+
* $PostgreSQL: pgsql/src/backend/utils/sort/tuplestore.c,v 1.26 2006/03/04 19:30:12 tgl Exp $
4040
*
4141
*-------------------------------------------------------------------------
4242
*/
@@ -316,15 +316,28 @@ tuplestore_puttuple(Tuplestorestate *state, void *tuple)
316316
switch (state->status)
317317
{
318318
case TSS_INMEM:
319-
/* Grow the array as needed */
320-
if (state->memtupcount >= state->memtupsize)
319+
/*
320+
* Grow the array as needed. Note that we try to grow the array
321+
* when there is still one free slot remaining --- if we fail,
322+
* there'll still be room to store the incoming tuple, and then
323+
* we'll switch to tape-based operation.
324+
*/
325+
if (state->memtupcount >= state->memtupsize - 1)
321326
{
322-
FREEMEM(state, GetMemoryChunkSpace(state->memtuples));
323-
state->memtupsize *= 2;
324-
state->memtuples = (void **)
325-
repalloc(state->memtuples,
326-
state->memtupsize * sizeof(void *));
327-
USEMEM(state, GetMemoryChunkSpace(state->memtuples));
327+
/*
328+
* See grow_memtuples() in tuplesort.c for the rationale
329+
* behind these two tests.
330+
*/
331+
if (state->availMem > (long) (state->memtupsize * sizeof(void *)) &&
332+
(Size) (state->memtupsize * 2) < MaxAllocSize / sizeof(void *))
333+
{
334+
FREEMEM(state, GetMemoryChunkSpace(state->memtuples));
335+
state->memtupsize *= 2;
336+
state->memtuples = (void **)
337+
repalloc(state->memtuples,
338+
state->memtupsize * sizeof(void *));
339+
USEMEM(state, GetMemoryChunkSpace(state->memtuples));
340+
}
328341
}
329342

330343
/* Stash the tuple in the in-memory array */
@@ -335,9 +348,9 @@ tuplestore_puttuple(Tuplestorestate *state, void *tuple)
335348
state->current = state->memtupcount;
336349

337350
/*
338-
* Done if we still fit in available memory.
351+
* Done if we still fit in available memory and have array slots.
339352
*/
340-
if (!LACKMEM(state))
353+
if (state->memtupcount < state->memtupsize && !LACKMEM(state))
341354
return;
342355

343356
/*

0 commit comments

Comments
 (0)