diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/utils/mmgr/aset.c | 10 | ||||
-rw-r--r-- | src/backend/utils/sort/tuplesort.c | 11 | ||||
-rw-r--r-- | src/backend/utils/sort/tuplestore.c | 11 | ||||
-rw-r--r-- | src/include/utils/memutils.h | 8 |
4 files changed, 34 insertions, 6 deletions
diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c index 23b345bb595..2baa237538f 100644 --- a/src/backend/utils/mmgr/aset.c +++ b/src/backend/utils/mmgr/aset.c @@ -89,9 +89,9 @@ * * With the current parameters, request sizes up to 8K are treated as chunks, * larger requests go into dedicated blocks. Change ALLOCSET_NUM_FREELISTS - * to adjust the boundary point. (But in contexts with small maxBlockSize, - * we may set the allocChunkLimit to less than 8K, so as to avoid space - * wastage.) + * to adjust the boundary point; and adjust ALLOCSET_SEPARATE_THRESHOLD in + * memutils.h to agree. (Note: in contexts with small maxBlockSize, we may + * set the allocChunkLimit to less than 8K, so as to avoid space wastage.) *-------------------- */ @@ -393,7 +393,11 @@ AllocSetContextCreate(MemoryContext parent, * We have to have allocChunkLimit a power of two, because the requested * and actually-allocated sizes of any chunk must be on the same side of * the limit, else we get confused about whether the chunk is "big". + * + * Also, allocChunkLimit must not exceed ALLOCSET_SEPARATE_THRESHOLD. */ + Assert(ALLOC_CHUNK_LIMIT == ALLOCSET_SEPARATE_THRESHOLD); + context->allocChunkLimit = ALLOC_CHUNK_LIMIT; while ((Size) (context->allocChunkLimit + ALLOC_CHUNKHDRSZ) > (Size) ((maxBlockSize - ALLOC_BLOCKHDRSZ) / ALLOC_CHUNK_FRACTION)) diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index b6b06d56856..11feb9622b6 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -557,7 +557,14 @@ tuplesort_begin_common(int workMem, bool randomAccess) state->tapeset = NULL; state->memtupcount = 0; - state->memtupsize = 1024; /* initial guess */ + + /* + * Initial size of array must be more than ALLOCSET_SEPARATE_THRESHOLD; + * see comments in grow_memtuples(). + */ + state->memtupsize = Max(1024, + ALLOCSET_SEPARATE_THRESHOLD / sizeof(SortTuple) + 1); + state->memtuples = (SortTuple *) palloc(state->memtupsize * sizeof(SortTuple)); USEMEM(state, GetMemoryChunkSpace(state->memtuples)); @@ -1000,7 +1007,7 @@ grow_memtuples(Tuplesortstate *state) state->memtupsize * sizeof(SortTuple)); USEMEM(state, GetMemoryChunkSpace(state->memtuples)); if (LACKMEM(state)) - elog(ERROR, "unexpected out-of-memory situation during sort"); + elog(ERROR, "unexpected out-of-memory situation in tuplesort"); return true; } diff --git a/src/backend/utils/sort/tuplestore.c b/src/backend/utils/sort/tuplestore.c index 9739c6bbed6..587de449e15 100644 --- a/src/backend/utils/sort/tuplestore.c +++ b/src/backend/utils/sort/tuplestore.c @@ -261,7 +261,14 @@ tuplestore_begin_common(int eflags, bool interXact, int maxKBytes) state->memtupdeleted = 0; state->memtupcount = 0; - state->memtupsize = 1024; /* initial guess */ + + /* + * Initial size of array must be more than ALLOCSET_SEPARATE_THRESHOLD; + * see comments in grow_memtuples(). + */ + state->memtupsize = Max(16384 / sizeof(void *), + ALLOCSET_SEPARATE_THRESHOLD / sizeof(void *) + 1); + state->memtuples = (void **) palloc(state->memtupsize * sizeof(void *)); USEMEM(state, GetMemoryChunkSpace(state->memtuples)); @@ -644,6 +651,8 @@ tuplestore_puttuple_common(Tuplestorestate *state, void *tuple) repalloc(state->memtuples, state->memtupsize * sizeof(void *)); USEMEM(state, GetMemoryChunkSpace(state->memtuples)); + if (LACKMEM(state)) + elog(ERROR, "unexpected out-of-memory situation in tuplestore"); } } diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h index f5427ac275f..747d517210d 100644 --- a/src/include/utils/memutils.h +++ b/src/include/utils/memutils.h @@ -138,4 +138,12 @@ extern MemoryContext AllocSetContextCreate(MemoryContext parent, #define ALLOCSET_SMALL_INITSIZE (1 * 1024) #define ALLOCSET_SMALL_MAXSIZE (8 * 1024) +/* + * Threshold above which a request in an AllocSet context is certain to be + * allocated separately (and thereby have constant allocation overhead). + * Few callers should be interested in this, but tuplesort/tuplestore need + * to know it. + */ +#define ALLOCSET_SEPARATE_THRESHOLD 8192 + #endif /* MEMUTILS_H */ |