aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/mmgr/aset.c10
-rw-r--r--src/backend/utils/sort/tuplesort.c11
-rw-r--r--src/backend/utils/sort/tuplestore.c11
-rw-r--r--src/include/utils/memutils.h8
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 */