Add repalloc0 and repalloc0_array
These zero out the space added by repalloc. This is a common pattern that is quite hairy to code by hand. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://www.postgresql.org/message-id/b66dfc89-9365-cb57-4e1f-b7d31813eeec@enterprisedb.com
This commit is contained in:
parent
30d98e14a8
commit
b4b7ce8061
@ -940,12 +940,8 @@ ExecHashIncreaseNumBatches(HashJoinTable hashtable)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* enlarge arrays and zero out added entries */
|
/* enlarge arrays and zero out added entries */
|
||||||
hashtable->innerBatchFile = repalloc_array(hashtable->innerBatchFile, BufFile *, nbatch);
|
hashtable->innerBatchFile = repalloc0_array(hashtable->innerBatchFile, BufFile *, oldnbatch, nbatch);
|
||||||
hashtable->outerBatchFile = repalloc_array(hashtable->outerBatchFile, BufFile *, nbatch);
|
hashtable->outerBatchFile = repalloc0_array(hashtable->outerBatchFile, BufFile *, oldnbatch, nbatch);
|
||||||
MemSet(hashtable->innerBatchFile + oldnbatch, 0,
|
|
||||||
(nbatch - oldnbatch) * sizeof(BufFile *));
|
|
||||||
MemSet(hashtable->outerBatchFile + oldnbatch, 0,
|
|
||||||
(nbatch - oldnbatch) * sizeof(BufFile *));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryContextSwitchTo(oldcxt);
|
MemoryContextSwitchTo(oldcxt);
|
||||||
|
@ -696,19 +696,16 @@ newLOfd(void)
|
|||||||
newsize = 64;
|
newsize = 64;
|
||||||
cookies = (LargeObjectDesc **)
|
cookies = (LargeObjectDesc **)
|
||||||
MemoryContextAllocZero(fscxt, newsize * sizeof(LargeObjectDesc *));
|
MemoryContextAllocZero(fscxt, newsize * sizeof(LargeObjectDesc *));
|
||||||
cookies_size = newsize;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Double size of array */
|
/* Double size of array */
|
||||||
i = cookies_size;
|
i = cookies_size;
|
||||||
newsize = cookies_size * 2;
|
newsize = cookies_size * 2;
|
||||||
cookies = (LargeObjectDesc **)
|
cookies =
|
||||||
repalloc(cookies, newsize * sizeof(LargeObjectDesc *));
|
repalloc0_array(cookies, LargeObjectDesc *, cookies_size, newsize);
|
||||||
MemSet(cookies + cookies_size, 0,
|
|
||||||
(newsize - cookies_size) * sizeof(LargeObjectDesc *));
|
|
||||||
cookies_size = newsize;
|
|
||||||
}
|
}
|
||||||
|
cookies_size = newsize;
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -133,16 +133,11 @@ find_placeholder_info(PlannerInfo *root, PlaceHolderVar *phv)
|
|||||||
while (phinfo->phid >= new_size)
|
while (phinfo->phid >= new_size)
|
||||||
new_size *= 2;
|
new_size *= 2;
|
||||||
if (root->placeholder_array)
|
if (root->placeholder_array)
|
||||||
{
|
root->placeholder_array =
|
||||||
root->placeholder_array = (PlaceHolderInfo **)
|
repalloc0_array(root->placeholder_array, PlaceHolderInfo *, root->placeholder_array_size, new_size);
|
||||||
repalloc(root->placeholder_array,
|
|
||||||
sizeof(PlaceHolderInfo *) * new_size);
|
|
||||||
MemSet(root->placeholder_array + root->placeholder_array_size, 0,
|
|
||||||
sizeof(PlaceHolderInfo *) * (new_size - root->placeholder_array_size));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
root->placeholder_array = (PlaceHolderInfo **)
|
root->placeholder_array =
|
||||||
palloc0(new_size * sizeof(PlaceHolderInfo *));
|
palloc0_array(PlaceHolderInfo *, new_size);
|
||||||
root->placeholder_array_size = new_size;
|
root->placeholder_array_size = new_size;
|
||||||
}
|
}
|
||||||
root->placeholder_array[phinfo->phid] = phinfo;
|
root->placeholder_array[phinfo->phid] = phinfo;
|
||||||
|
@ -157,31 +157,18 @@ expand_planner_arrays(PlannerInfo *root, int add_size)
|
|||||||
|
|
||||||
new_size = root->simple_rel_array_size + add_size;
|
new_size = root->simple_rel_array_size + add_size;
|
||||||
|
|
||||||
root->simple_rel_array = (RelOptInfo **)
|
root->simple_rel_array =
|
||||||
repalloc(root->simple_rel_array,
|
repalloc0_array(root->simple_rel_array, RelOptInfo *, root->simple_rel_array_size, new_size);
|
||||||
sizeof(RelOptInfo *) * new_size);
|
|
||||||
MemSet(root->simple_rel_array + root->simple_rel_array_size,
|
|
||||||
0, sizeof(RelOptInfo *) * add_size);
|
|
||||||
|
|
||||||
root->simple_rte_array = (RangeTblEntry **)
|
root->simple_rte_array =
|
||||||
repalloc(root->simple_rte_array,
|
repalloc0_array(root->simple_rte_array, RangeTblEntry *, root->simple_rel_array_size, new_size);
|
||||||
sizeof(RangeTblEntry *) * new_size);
|
|
||||||
MemSet(root->simple_rte_array + root->simple_rel_array_size,
|
|
||||||
0, sizeof(RangeTblEntry *) * add_size);
|
|
||||||
|
|
||||||
if (root->append_rel_array)
|
if (root->append_rel_array)
|
||||||
{
|
root->append_rel_array =
|
||||||
root->append_rel_array = (AppendRelInfo **)
|
repalloc0_array(root->append_rel_array, AppendRelInfo *, root->simple_rel_array_size, new_size);
|
||||||
repalloc(root->append_rel_array,
|
|
||||||
sizeof(AppendRelInfo *) * new_size);
|
|
||||||
MemSet(root->append_rel_array + root->simple_rel_array_size,
|
|
||||||
0, sizeof(AppendRelInfo *) * add_size);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
root->append_rel_array =
|
||||||
root->append_rel_array = (AppendRelInfo **)
|
palloc0_array(AppendRelInfo *, new_size);
|
||||||
palloc0(sizeof(AppendRelInfo *) * new_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
root->simple_rel_array_size = new_size;
|
root->simple_rel_array_size = new_size;
|
||||||
}
|
}
|
||||||
|
@ -145,14 +145,10 @@ variable_paramref_hook(ParseState *pstate, ParamRef *pref)
|
|||||||
{
|
{
|
||||||
/* Need to enlarge param array */
|
/* Need to enlarge param array */
|
||||||
if (*parstate->paramTypes)
|
if (*parstate->paramTypes)
|
||||||
*parstate->paramTypes = (Oid *) repalloc(*parstate->paramTypes,
|
*parstate->paramTypes = repalloc0_array(*parstate->paramTypes, Oid,
|
||||||
paramno * sizeof(Oid));
|
*parstate->numParams, paramno);
|
||||||
else
|
else
|
||||||
*parstate->paramTypes = (Oid *) palloc(paramno * sizeof(Oid));
|
*parstate->paramTypes = palloc0_array(Oid, paramno);
|
||||||
/* Zero out the previously-unreferenced slots */
|
|
||||||
MemSet(*parstate->paramTypes + *parstate->numParams,
|
|
||||||
0,
|
|
||||||
(paramno - *parstate->numParams) * sizeof(Oid));
|
|
||||||
*parstate->numParams = paramno;
|
*parstate->numParams = paramno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,13 +668,8 @@ LWLockRegisterTranche(int tranche_id, const char *tranche_name)
|
|||||||
MemoryContextAllocZero(TopMemoryContext,
|
MemoryContextAllocZero(TopMemoryContext,
|
||||||
newalloc * sizeof(char *));
|
newalloc * sizeof(char *));
|
||||||
else
|
else
|
||||||
{
|
LWLockTrancheNames =
|
||||||
LWLockTrancheNames = (const char **)
|
repalloc0_array(LWLockTrancheNames, const char *, LWLockTrancheNamesAllocated, newalloc);
|
||||||
repalloc(LWLockTrancheNames, newalloc * sizeof(char *));
|
|
||||||
memset(LWLockTrancheNames + LWLockTrancheNamesAllocated,
|
|
||||||
0,
|
|
||||||
(newalloc - LWLockTrancheNamesAllocated) * sizeof(char *));
|
|
||||||
}
|
|
||||||
LWLockTrancheNamesAllocated = newalloc;
|
LWLockTrancheNamesAllocated = newalloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4855,14 +4855,9 @@ expand_colnames_array_to(deparse_columns *colinfo, int n)
|
|||||||
if (n > colinfo->num_cols)
|
if (n > colinfo->num_cols)
|
||||||
{
|
{
|
||||||
if (colinfo->colnames == NULL)
|
if (colinfo->colnames == NULL)
|
||||||
colinfo->colnames = (char **) palloc0(n * sizeof(char *));
|
colinfo->colnames = palloc0_array(char *, n);
|
||||||
else
|
else
|
||||||
{
|
colinfo->colnames = repalloc0_array(colinfo->colnames, char *, colinfo->num_cols, n);
|
||||||
colinfo->colnames = (char **) repalloc(colinfo->colnames,
|
|
||||||
n * sizeof(char *));
|
|
||||||
memset(colinfo->colnames + colinfo->num_cols, 0,
|
|
||||||
(n - colinfo->num_cols) * sizeof(char *));
|
|
||||||
}
|
|
||||||
colinfo->num_cols = n;
|
colinfo->num_cols = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
src/backend/utils/cache/typcache.c
vendored
10
src/backend/utils/cache/typcache.c
vendored
@ -1714,14 +1714,8 @@ ensure_record_cache_typmod_slot_exists(int32 typmod)
|
|||||||
{
|
{
|
||||||
int32 newlen = pg_nextpower2_32(typmod + 1);
|
int32 newlen = pg_nextpower2_32(typmod + 1);
|
||||||
|
|
||||||
RecordCacheArray = (TupleDesc *) repalloc(RecordCacheArray,
|
RecordCacheArray = repalloc0_array(RecordCacheArray, TupleDesc, RecordCacheArrayLen, newlen);
|
||||||
newlen * sizeof(TupleDesc));
|
RecordIdentifierArray = repalloc0_array(RecordIdentifierArray, uint64, RecordCacheArrayLen, newlen);
|
||||||
memset(RecordCacheArray + RecordCacheArrayLen, 0,
|
|
||||||
(newlen - RecordCacheArrayLen) * sizeof(TupleDesc));
|
|
||||||
RecordIdentifierArray = (uint64 *) repalloc(RecordIdentifierArray,
|
|
||||||
newlen * sizeof(uint64));
|
|
||||||
memset(RecordIdentifierArray + RecordCacheArrayLen, 0,
|
|
||||||
(newlen - RecordCacheArrayLen) * sizeof(uint64));
|
|
||||||
RecordCacheArrayLen = newlen;
|
RecordCacheArrayLen = newlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1395,6 +1395,26 @@ repalloc_extended(void *pointer, Size size, int flags)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* repalloc0
|
||||||
|
* Adjust the size of a previously allocated chunk and zero out the added
|
||||||
|
* space.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
repalloc0(void *pointer, Size oldsize, Size size)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
/* catch wrong argument order */
|
||||||
|
if (unlikely(oldsize > size))
|
||||||
|
elog(ERROR, "invalid repalloc0 call: oldsize %zu, new size %zu",
|
||||||
|
oldsize, size);
|
||||||
|
|
||||||
|
ret = repalloc(pointer, size);
|
||||||
|
memset((char *) ret + oldsize, 0, (size - oldsize));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MemoryContextAllocHuge
|
* MemoryContextAllocHuge
|
||||||
* Allocate (possibly-expansive) space within the specified context.
|
* Allocate (possibly-expansive) space within the specified context.
|
||||||
|
@ -80,6 +80,7 @@ extern void *palloc_extended(Size size, int flags);
|
|||||||
extern pg_nodiscard void *repalloc(void *pointer, Size size);
|
extern pg_nodiscard void *repalloc(void *pointer, Size size);
|
||||||
extern pg_nodiscard void *repalloc_extended(void *pointer,
|
extern pg_nodiscard void *repalloc_extended(void *pointer,
|
||||||
Size size, int flags);
|
Size size, int flags);
|
||||||
|
extern pg_nodiscard void *repalloc0(void *pointer, Size oldsize, Size size);
|
||||||
extern void pfree(void *pointer);
|
extern void pfree(void *pointer);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -103,6 +104,7 @@ extern void pfree(void *pointer);
|
|||||||
* objects of type "type"
|
* objects of type "type"
|
||||||
*/
|
*/
|
||||||
#define repalloc_array(pointer, type, count) ((type *) repalloc(pointer, sizeof(type) * (count)))
|
#define repalloc_array(pointer, type, count) ((type *) repalloc(pointer, sizeof(type) * (count)))
|
||||||
|
#define repalloc0_array(pointer, type, oldcount, count) ((type *) repalloc0(pointer, sizeof(type) * (oldcount), sizeof(type) * (count)))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The result of palloc() is always word-aligned, so we can skip testing
|
* The result of palloc() is always word-aligned, so we can skip testing
|
||||||
|
Loading…
x
Reference in New Issue
Block a user