|
11 | 11 | * Portions Copyright (c) 1994, Regents of the University of California |
12 | 12 | * |
13 | 13 | * IDENTIFICATION |
14 | | - * $PostgreSQL: pgsql/src/backend/utils/mmgr/aset.c,v 1.68 2006/10/04 00:30:04 momjian Exp $ |
| 14 | + * $PostgreSQL: pgsql/src/backend/utils/mmgr/aset.c,v 1.69 2006/11/08 19:27:24 tgl Exp $ |
15 | 15 | * |
16 | 16 | * NOTE: |
17 | 17 | * This is a new (Feb. 05, 1999) implementation of the allocation set |
@@ -140,6 +140,7 @@ typedef struct AllocSetContext |
140 | 140 | /* Allocation parameters for this context: */ |
141 | 141 | Size initBlockSize; /* initial block size */ |
142 | 142 | Size maxBlockSize; /* maximum block size */ |
| 143 | + Size nextBlockSize; /* next block size to allocate */ |
143 | 144 | AllocBlock keeper; /* if not NULL, keep this block over resets */ |
144 | 145 | } AllocSetContext; |
145 | 146 |
|
@@ -325,6 +326,7 @@ AllocSetContextCreate(MemoryContext parent, |
325 | 326 | maxBlockSize = initBlockSize; |
326 | 327 | context->initBlockSize = initBlockSize; |
327 | 328 | context->maxBlockSize = maxBlockSize; |
| 329 | + context->nextBlockSize = initBlockSize; |
328 | 330 |
|
329 | 331 | /* |
330 | 332 | * Grab always-allocated space, if requested |
@@ -443,6 +445,9 @@ AllocSetReset(MemoryContext context) |
443 | 445 | block = next; |
444 | 446 | } |
445 | 447 |
|
| 448 | + /* Reset block size allocation sequence, too */ |
| 449 | + set->nextBlockSize = set->initBlockSize; |
| 450 | + |
446 | 451 | set->isReset = true; |
447 | 452 | } |
448 | 453 |
|
@@ -665,28 +670,14 @@ AllocSetAlloc(MemoryContext context, Size size) |
665 | 670 | { |
666 | 671 | Size required_size; |
667 | 672 |
|
668 | | - if (set->blocks == NULL) |
669 | | - { |
670 | | - /* First block of the alloc set, use initBlockSize */ |
671 | | - blksize = set->initBlockSize; |
672 | | - } |
673 | | - else |
674 | | - { |
675 | | - /* |
676 | | - * Use first power of 2 that is larger than previous block, but |
677 | | - * not more than the allowed limit. (We don't simply double the |
678 | | - * prior block size, because in some cases this could be a funny |
679 | | - * size, eg if very first allocation was for an odd-sized large |
680 | | - * chunk.) |
681 | | - */ |
682 | | - Size pblksize = set->blocks->endptr - ((char *) set->blocks); |
683 | | - |
684 | | - blksize = set->initBlockSize; |
685 | | - while (blksize <= pblksize) |
686 | | - blksize <<= 1; |
687 | | - if (blksize > set->maxBlockSize) |
688 | | - blksize = set->maxBlockSize; |
689 | | - } |
| 673 | + /* |
| 674 | + * The first such block has size initBlockSize, and we double the |
| 675 | + * space in each succeeding block, but not more than maxBlockSize. |
| 676 | + */ |
| 677 | + blksize = set->nextBlockSize; |
| 678 | + set->nextBlockSize <<= 1; |
| 679 | + if (set->nextBlockSize > set->maxBlockSize) |
| 680 | + set->nextBlockSize = set->maxBlockSize; |
690 | 681 |
|
691 | 682 | /* |
692 | 683 | * If initBlockSize is less than ALLOC_CHUNK_LIMIT, we could need more |
@@ -734,11 +725,8 @@ AllocSetAlloc(MemoryContext context, Size size) |
734 | 725 | * never need any space. Don't mark an oversize block as a keeper, |
735 | 726 | * however. |
736 | 727 | */ |
737 | | - if (set->blocks == NULL && blksize == set->initBlockSize) |
738 | | - { |
739 | | - Assert(set->keeper == NULL); |
| 728 | + if (set->keeper == NULL && blksize == set->initBlockSize) |
740 | 729 | set->keeper = block; |
741 | | - } |
742 | 730 |
|
743 | 731 | block->next = set->blocks; |
744 | 732 | set->blocks = block; |
|
0 commit comments