/* * Manage the allocation state of the array * * Note that the array needs to be in a reasonably long-lived context, * ie the Agg node's aggcontext. */ static PGARRAY * GetPGArray(PGARRAY * p, AggState *aggstate, bool fAdd) { if (!p) { /* New array */ int cb = PGARRAY_SIZE(START_NUM); p = (PGARRAY *) MemoryContextAlloc(aggstate->aggcontext, cb); p->a.size = cb; p->a.ndim = 1; p->a.flags = 0; p->a.elemtype = INT4OID; p->items = 0; p->lower = START_NUM; } else if (fAdd) { /* Ensure array has space for another item */ if (p->items >= p->lower) { PGARRAY *pn; int n = p->lower * 2; int cbNew = PGARRAY_SIZE(n); pn = (PGARRAY *) MemoryContextAlloc(aggstate->aggcontext, cbNew); memcpy(pn, p, p->a.size); pn->a.size = cbNew; pn->lower = n; /* do not pfree(p), because nodeAgg.c will */ p = pn; } } return p; }
/* * Manage the aggregation state of the array * * Need to specify a suitably long-lived memory context, or it will vanish! * PortalContext isn't really right, but it's close enough. */ static PGARRAY * GetPGArray(PGARRAY *p, int fAdd) { if (!p) { /* New array */ int cb = PGARRAY_SIZE(START_NUM); p = (PGARRAY *) MemoryContextAlloc(PortalContext, cb); p->a.size = cb; p->a.ndim = 0; p->a.flags = 0; p->a.elemtype = INT4OID; p->items = 0; p->lower = START_NUM; } else if (fAdd) { /* Ensure array has space */ if (p->items >= p->lower) { PGARRAY *pn; int n = p->lower + p->lower; int cbNew = PGARRAY_SIZE(n); pn = (PGARRAY *) repalloc(p, cbNew); pn->a.size = cbNew; pn->lower = n; return pn; } } return p; }
/* Shrinks the array to its actual size and moves it into the standard * memory allocation context, frees working memory */ static PGARRAY * ShrinkPGArray(PGARRAY * p) { PGARRAY *pnew = NULL; if (p) { /* get target size */ int cb = PGARRAY_SIZE(p->items); /* use current transaction context */ pnew = palloc(cb); /* * Fix up the fields in the new structure, so Postgres understands */ memcpy(pnew, p, cb); pnew->a.size = cb; pnew->a.ndim = 1; pnew->a.flags = 0; pnew->a.elemtype = INT4OID; pnew->lower = 1; pfree(p); } return pnew; }
/* * Shrinks the array to its actual size and moves it into the standard * memory allocation context */ static PGARRAY * ShrinkPGArray(PGARRAY * p) { PGARRAY *pnew; /* get target size */ int cb = PGARRAY_SIZE(p->items); /* use current transaction context */ pnew = palloc(cb); memcpy(pnew, p, cb); /* fix up the fields in the new array to match normal conventions */ pnew->a.size = cb; pnew->lower = 1; /* do not pfree(p), because nodeAgg.c will */ return pnew; }