Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 6755558

Browse files
committed
Improve aset.c's space management in contexts with small maxBlockSize.
The previous coding would allow requests up to half of maxBlockSize to be treated as "chunks", but when that actually did happen, we'd waste nearly half of the space in the malloc block containing the chunk, if no smaller requests came along to fill it. Avoid this scenario by limiting the maximum size of a chunk to 1/8th maxBlockSize, so that we can waste no more than 1/8th of the allocated space. This will not change the behavior at all for the default context size parameters (with large maxBlockSize), but it will change the behavior when using ALLOCSET_SMALL_MAXSIZE. In particular, there's no longer a need for spell.c to be overly concerned about the request size parameters it uses, so remove a rather unhelpful comment about that. Merlin Moncure, per an idea of Tom Lane's
1 parent 5c436a7 commit 6755558

File tree

2 files changed

+18
-9
lines changed

2 files changed

+18
-9
lines changed

src/backend/tsearch/spell.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ NIFinishBuild(IspellDict *Conf)
7575
* doesn't need that. The cpalloc and cpalloc0 macros are just documentation
7676
* to indicate which allocations actually require zeroing.
7777
*/
78-
#define COMPACT_ALLOC_CHUNK 8192 /* must be > aset.c's allocChunkLimit */
78+
#define COMPACT_ALLOC_CHUNK 8192 /* amount to get from palloc at once */
7979
#define COMPACT_MAX_REQ 1024 /* must be < COMPACT_ALLOC_CHUNK */
8080

8181
static void *

src/backend/utils/mmgr/aset.c

+17-8
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,18 @@
8989
*
9090
* With the current parameters, request sizes up to 8K are treated as chunks,
9191
* larger requests go into dedicated blocks. Change ALLOCSET_NUM_FREELISTS
92-
* to adjust the boundary point.
92+
* to adjust the boundary point. (But in contexts with small maxBlockSize,
93+
* we may set the allocChunkLimit to less than 8K, so as to avoid space
94+
* wastage.)
9395
*--------------------
9496
*/
9597

9698
#define ALLOC_MINBITS 3 /* smallest chunk size is 8 bytes */
9799
#define ALLOCSET_NUM_FREELISTS 11
98100
#define ALLOC_CHUNK_LIMIT (1 << (ALLOCSET_NUM_FREELISTS-1+ALLOC_MINBITS))
99101
/* Size of largest chunk that we use a fixed size for */
102+
#define ALLOC_CHUNK_FRACTION 4
103+
/* We allow chunks to be at most 1/4 of maxBlockSize (less overhead) */
100104

101105
/*--------------------
102106
* The first block allocated for an allocset has size initBlockSize.
@@ -380,15 +384,20 @@ AllocSetContextCreate(MemoryContext parent,
380384
/*
381385
* Compute the allocation chunk size limit for this context. It can't be
382386
* more than ALLOC_CHUNK_LIMIT because of the fixed number of freelists.
383-
* If maxBlockSize is small then requests exceeding the maxBlockSize
384-
* should be treated as large chunks, too. We have to have
385-
* allocChunkLimit a power of two, because the requested and
386-
* actually-allocated sizes of any chunk must be on the same side of the
387-
* limit, else we get confused about whether the chunk is "big".
387+
* If maxBlockSize is small then requests exceeding the maxBlockSize, or
388+
* even a significant fraction of it, should be treated as large chunks
389+
* too. For the typical case of maxBlockSize a power of 2, the chunk size
390+
* limit will be at most 1/8th maxBlockSize, so that given a stream of
391+
* requests that are all the maximum chunk size we will waste at most
392+
* 1/8th of the allocated space.
393+
*
394+
* We have to have allocChunkLimit a power of two, because the requested
395+
* and actually-allocated sizes of any chunk must be on the same side of
396+
* the limit, else we get confused about whether the chunk is "big".
388397
*/
389398
context->allocChunkLimit = ALLOC_CHUNK_LIMIT;
390-
while (context->allocChunkLimit >
391-
(Size) (maxBlockSize - ALLOC_BLOCKHDRSZ - ALLOC_CHUNKHDRSZ))
399+
while ((Size) (context->allocChunkLimit + ALLOC_CHUNKHDRSZ) >
400+
(Size) ((maxBlockSize - ALLOC_BLOCKHDRSZ) / ALLOC_CHUNK_FRACTION))
392401
context->allocChunkLimit >>= 1;
393402

394403
/*

0 commit comments

Comments
 (0)