sortmem_grow-v3.patch
application/octet-stream
Filename: sortmem_grow-v3.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
Series: patch v3
| File | + | − |
|---|---|---|
| src/backend/utils/sort/tuplesort.c | 37 | 8 |
diff src/backend/utils/sort/tuplesort.c
index ce27e40..80ac11b
*** a/src/backend/utils/sort/tuplesort.c
--- b/src/backend/utils/sort/tuplesort.c
*************** tuplesort_end(Tuplesortstate *state)
*** 957,970 ****
* Grow the memtuples[] array, if possible within our memory constraint.
* Return TRUE if able to enlarge the array, FALSE if not.
*
! * At each increment we double the size of the array. When we are short
! * on memory we could consider smaller increases, but because availMem
! * moves around with tuple addition/removal, this might result in thrashing.
! * Small increases in the array size are likely to be pretty inefficient.
*/
static bool
grow_memtuples(Tuplesortstate *state)
{
/*
* We need to be sure that we do not cause LACKMEM to become true, else
* the space management algorithm will go nuts. We assume here that the
--- 957,974 ----
* Grow the memtuples[] array, if possible within our memory constraint.
* Return TRUE if able to enlarge the array, FALSE if not.
*
! * At each increment we double the size of the array. When we are short on
! * memory we do attempt one last, smaller increase. This only happens at most
! * once, since availMem moves around with tuple addition/removal. To do othewise
! * might result in thrashing. This is nothing more than a last-ditch effort to
! * avoid exceeding allowedMem, an undesirable outcome if avoidable.
*/
static bool
grow_memtuples(Tuplesortstate *state)
{
+ int newmemtupsize;
+ long memNowUsed = state->allowedMem - state->availMem;
+
/*
* We need to be sure that we do not cause LACKMEM to become true, else
* the space management algorithm will go nuts. We assume here that the
*************** grow_memtuples(Tuplesortstate *state)
*** 974,991 ****
* enough to force palloc to treat it as a separate chunk, so this
* assumption should be good. But let's check it.)
*/
! if (state->availMem <= (long) (state->memtupsize * sizeof(SortTuple)))
! return false;
/*
* On a 64-bit machine, allowedMem could be high enough to get us into
* trouble with MaxAllocSize, too.
*/
! if ((Size) (state->memtupsize * 2) >= MaxAllocSize / sizeof(SortTuple))
return false;
FREEMEM(state, GetMemoryChunkSpace(state->memtuples));
! state->memtupsize *= 2;
state->memtuples = (SortTuple *)
repalloc(state->memtuples,
state->memtupsize * sizeof(SortTuple));
--- 978,1020 ----
* enough to force palloc to treat it as a separate chunk, so this
* assumption should be good. But let's check it.)
*/
! if (memNowUsed > state->availMem)
! {
! int memtupsize = state->memtupsize;
! long allowedMem = state->allowedMem;
!
! /*
! * For this last increment, abandon doubling strategy.
! *
! * Use the known size (in bytes) of the tuples seen so far to estimate a
! * memtuples size that is just within our constraint. This is nothing
! * more than a heuristic.
! *
! * N.B. We rely on the assumption that nothing other than memtuples and
! * individual tuple storage has been deducted from availMem.
! */
! newmemtupsize = memtupsize * allowedMem / memNowUsed;
!
! Assert(newmemtupsize <= state->memtupsize * 2);
!
! /* This may not be our first time through */
! if (newmemtupsize <= memtupsize)
! return false;
! }
! else
! {
! newmemtupsize = state->memtupsize * 2;
! }
/*
* On a 64-bit machine, allowedMem could be high enough to get us into
* trouble with MaxAllocSize, too.
*/
! if ((Size) (newmemtupsize) >= MaxAllocSize / sizeof(SortTuple))
return false;
FREEMEM(state, GetMemoryChunkSpace(state->memtuples));
! state->memtupsize = newmemtupsize;
state->memtuples = (SortTuple *)
repalloc(state->memtuples,
state->memtupsize * sizeof(SortTuple));