diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2006-03-04 19:30:12 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2006-03-04 19:30:12 +0000 |
commit | 2689abf07849d1ed69dfe57e3a999b1c6bb5e603 (patch) | |
tree | 865d7ae21dadd2d2a1f674f749b19d6d7d22c21b | |
parent | 20bdc71369014f4cb1cf04fafbf99862cfbe2504 (diff) | |
download | postgresql-2689abf07849d1ed69dfe57e3a999b1c6bb5e603.tar.gz postgresql-2689abf07849d1ed69dfe57e3a999b1c6bb5e603.zip |
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.
-rw-r--r-- | src/backend/utils/sort/tuplestore.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/src/backend/utils/sort/tuplestore.c b/src/backend/utils/sort/tuplestore.c index bb4195f8829..ea868d4f539 100644 --- a/src/backend/utils/sort/tuplestore.c +++ b/src/backend/utils/sort/tuplestore.c @@ -36,7 +36,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * 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) switch (state->status) { 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; - state->memtuples = (void **) - repalloc(state->memtuples, - state->memtupsize * sizeof(void *)); - USEMEM(state, GetMemoryChunkSpace(state->memtuples)); + /* + * See grow_memtuples() in tuplesort.c for the rationale + * behind these two tests. + */ + if (state->availMem > (long) (state->memtupsize * sizeof(void *)) && + (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 */ @@ -335,9 +348,9 @@ tuplestore_puttuple(Tuplestorestate *state, void *tuple) 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; /* |