Commit c6e394c1 authored by Tom Lane's avatar Tom Lane

Small improvements for allocation logic in ginHeapTupleFastCollect().

Avoid repetitive calls to repalloc() when the required size of the
collector array grows more than 2x in one call.  Also ensure that the
array size is a power of 2 (since palloc will probably consume a power
of 2 anyway) and doesn't start out very small (which'd likely just lead
to extra repallocs).

David Rowley, tweaked a bit by me

Discussion: https://postgr.es/m/CAKJS1f8vn-iSBE8PKeVHrnhvyjRNYCxguPFFY08QLYmjWG9hPQ@mail.gmail.com
parent 63992424
......@@ -486,18 +486,41 @@ ginHeapTupleFastCollect(GinState *ginstate,
entries = ginExtractEntries(ginstate, attnum, value, isNull,
&nentries, &categories);
/*
* Protect against integer overflow in allocation calculations
*/
if (nentries < 0 ||
collector->ntuples + nentries > MaxAllocSize / sizeof(IndexTuple))
elog(ERROR, "too many entries for GIN index");
/*
* Allocate/reallocate memory for storing collected tuples
*/
if (collector->tuples == NULL)
{
collector->lentuples = nentries * ginstate->origTupdesc->natts;
/*
* Determine the number of elements to allocate in the tuples array
* initially. Make it a power of 2 to avoid wasting memory when
* resizing (since palloc likes powers of 2).
*/
collector->lentuples = 16;
while (collector->lentuples < nentries)
collector->lentuples *= 2;
collector->tuples = (IndexTuple *) palloc(sizeof(IndexTuple) * collector->lentuples);
}
while (collector->ntuples + nentries > collector->lentuples)
else if (collector->lentuples < collector->ntuples + nentries)
{
collector->lentuples *= 2;
/*
* Advance lentuples to the next suitable power of 2. This won't
* overflow, though we could get to a value that exceeds
* MaxAllocSize/sizeof(IndexTuple), causing an error in repalloc.
*/
do
{
collector->lentuples *= 2;
} while (collector->lentuples < collector->ntuples + nentries);
collector->tuples = (IndexTuple *) repalloc(collector->tuples,
sizeof(IndexTuple) * collector->lentuples);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment