REALLOCATE_BITMAPSETS manual compile-time option
This option forces each bitmapset modification to reallocate bitmapset. This is useful for debugging hangling pointers to bitmapset's. Discussion: https://postgr.es/m/CAMbWs4_wJthNtYBL%2BSsebpgF-5L2r5zFFk6xYbS0A78GKOTFHw%40mail.gmail.com Reviewed-by: Richard Guo, Andres Freund, Ashutosh Bapat, Andrei Lepikhov
This commit is contained in:
parent
71a3e8c43b
commit
7d58f2342b
@ -263,6 +263,7 @@ bms_intersect(const Bitmapset *a, const Bitmapset *b)
|
|||||||
/* Handle cases where either input is NULL */
|
/* Handle cases where either input is NULL */
|
||||||
if (a == NULL || b == NULL)
|
if (a == NULL || b == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Identify shorter and longer input; copy the shorter one */
|
/* Identify shorter and longer input; copy the shorter one */
|
||||||
if (a->nwords <= b->nwords)
|
if (a->nwords <= b->nwords)
|
||||||
{
|
{
|
||||||
@ -798,8 +799,15 @@ bms_add_member(Bitmapset *a, int x)
|
|||||||
{
|
{
|
||||||
int oldnwords = a->nwords;
|
int oldnwords = a->nwords;
|
||||||
int i;
|
int i;
|
||||||
|
#ifdef REALLOCATE_BITMAPSETS
|
||||||
|
Bitmapset *tmp = a;
|
||||||
|
|
||||||
|
a = (Bitmapset *) palloc(BITMAPSET_SIZE(wordnum + 1));
|
||||||
|
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
|
||||||
|
pfree(tmp);
|
||||||
|
#else
|
||||||
a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(wordnum + 1));
|
a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(wordnum + 1));
|
||||||
|
#endif
|
||||||
a->nwords = wordnum + 1;
|
a->nwords = wordnum + 1;
|
||||||
/* zero out the enlarged portion */
|
/* zero out the enlarged portion */
|
||||||
i = oldnwords;
|
i = oldnwords;
|
||||||
@ -808,6 +816,16 @@ bms_add_member(Bitmapset *a, int x)
|
|||||||
a->words[i] = 0;
|
a->words[i] = 0;
|
||||||
} while (++i < a->nwords);
|
} while (++i < a->nwords);
|
||||||
}
|
}
|
||||||
|
#ifdef REALLOCATE_BITMAPSETS
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Bitmapset *tmp = a;
|
||||||
|
|
||||||
|
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
|
||||||
|
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
|
||||||
|
pfree(tmp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
a->words[wordnum] |= ((bitmapword) 1 << bitnum);
|
a->words[wordnum] |= ((bitmapword) 1 << bitnum);
|
||||||
return a;
|
return a;
|
||||||
@ -825,6 +843,9 @@ bms_del_member(Bitmapset *a, int x)
|
|||||||
{
|
{
|
||||||
int wordnum,
|
int wordnum,
|
||||||
bitnum;
|
bitnum;
|
||||||
|
#ifdef REALLOCATE_BITMAPSETS
|
||||||
|
Bitmapset *tmp = a;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (x < 0)
|
if (x < 0)
|
||||||
elog(ERROR, "negative bitmapset member not allowed");
|
elog(ERROR, "negative bitmapset member not allowed");
|
||||||
@ -836,6 +857,12 @@ bms_del_member(Bitmapset *a, int x)
|
|||||||
wordnum = WORDNUM(x);
|
wordnum = WORDNUM(x);
|
||||||
bitnum = BITNUM(x);
|
bitnum = BITNUM(x);
|
||||||
|
|
||||||
|
#ifdef REALLOCATE_BITMAPSETS
|
||||||
|
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
|
||||||
|
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
|
||||||
|
pfree(tmp);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* member can't exist. Return 'a' unmodified */
|
/* member can't exist. Return 'a' unmodified */
|
||||||
if (unlikely(wordnum >= a->nwords))
|
if (unlikely(wordnum >= a->nwords))
|
||||||
return a;
|
return a;
|
||||||
@ -889,6 +916,13 @@ bms_add_members(Bitmapset *a, const Bitmapset *b)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef REALLOCATE_BITMAPSETS
|
||||||
|
Bitmapset *tmp = a;
|
||||||
|
|
||||||
|
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
|
||||||
|
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
|
||||||
|
pfree(tmp);
|
||||||
|
#endif
|
||||||
result = a;
|
result = a;
|
||||||
other = b;
|
other = b;
|
||||||
}
|
}
|
||||||
@ -941,9 +975,16 @@ bms_add_range(Bitmapset *a, int lower, int upper)
|
|||||||
{
|
{
|
||||||
int oldnwords = a->nwords;
|
int oldnwords = a->nwords;
|
||||||
int i;
|
int i;
|
||||||
|
#ifdef REALLOCATE_BITMAPSETS
|
||||||
|
Bitmapset *tmp = a;
|
||||||
|
|
||||||
|
a = (Bitmapset *) palloc(BITMAPSET_SIZE(uwordnum + 1));
|
||||||
|
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
|
||||||
|
pfree(tmp);
|
||||||
|
#else
|
||||||
/* ensure we have enough words to store the upper bit */
|
/* ensure we have enough words to store the upper bit */
|
||||||
a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(uwordnum + 1));
|
a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(uwordnum + 1));
|
||||||
|
#endif
|
||||||
a->nwords = uwordnum + 1;
|
a->nwords = uwordnum + 1;
|
||||||
/* zero out the enlarged portion */
|
/* zero out the enlarged portion */
|
||||||
i = oldnwords;
|
i = oldnwords;
|
||||||
@ -992,6 +1033,12 @@ bms_int_members(Bitmapset *a, const Bitmapset *b)
|
|||||||
int lastnonzero;
|
int lastnonzero;
|
||||||
int shortlen;
|
int shortlen;
|
||||||
int i;
|
int i;
|
||||||
|
#ifdef REALLOCATE_BITMAPSETS
|
||||||
|
Bitmapset *tmp = a;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Assert(a == NULL || IsA(a, Bitmapset));
|
||||||
|
Assert(b == NULL || IsA(b, Bitmapset));
|
||||||
|
|
||||||
Assert(a == NULL || IsA(a, Bitmapset));
|
Assert(a == NULL || IsA(a, Bitmapset));
|
||||||
Assert(b == NULL || IsA(b, Bitmapset));
|
Assert(b == NULL || IsA(b, Bitmapset));
|
||||||
@ -1004,6 +1051,13 @@ bms_int_members(Bitmapset *a, const Bitmapset *b)
|
|||||||
pfree(a);
|
pfree(a);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef REALLOCATE_BITMAPSETS
|
||||||
|
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
|
||||||
|
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
|
||||||
|
pfree(tmp);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Intersect b into a; we need never copy */
|
/* Intersect b into a; we need never copy */
|
||||||
shortlen = Min(a->nwords, b->nwords);
|
shortlen = Min(a->nwords, b->nwords);
|
||||||
lastnonzero = -1;
|
lastnonzero = -1;
|
||||||
@ -1035,6 +1089,9 @@ Bitmapset *
|
|||||||
bms_del_members(Bitmapset *a, const Bitmapset *b)
|
bms_del_members(Bitmapset *a, const Bitmapset *b)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
#ifdef REALLOCATE_BITMAPSETS
|
||||||
|
Bitmapset *tmp = a;
|
||||||
|
#endif
|
||||||
|
|
||||||
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
|
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
|
||||||
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
|
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
|
||||||
@ -1044,6 +1101,13 @@ bms_del_members(Bitmapset *a, const Bitmapset *b)
|
|||||||
return NULL;
|
return NULL;
|
||||||
if (b == NULL)
|
if (b == NULL)
|
||||||
return a;
|
return a;
|
||||||
|
|
||||||
|
#ifdef REALLOCATE_BITMAPSETS
|
||||||
|
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
|
||||||
|
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
|
||||||
|
pfree(tmp);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Remove b's bits from a; we need never copy */
|
/* Remove b's bits from a; we need never copy */
|
||||||
if (a->nwords > b->nwords)
|
if (a->nwords > b->nwords)
|
||||||
{
|
{
|
||||||
@ -1096,6 +1160,12 @@ bms_join(Bitmapset *a, Bitmapset *b)
|
|||||||
Bitmapset *other;
|
Bitmapset *other;
|
||||||
int otherlen;
|
int otherlen;
|
||||||
int i;
|
int i;
|
||||||
|
#ifdef REALLOCATE_BITMAPSETS
|
||||||
|
Bitmapset *tmp = a;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Assert(a == NULL || IsA(a, Bitmapset));
|
||||||
|
Assert(b == NULL || IsA(b, Bitmapset));
|
||||||
|
|
||||||
Assert(a == NULL || IsA(a, Bitmapset));
|
Assert(a == NULL || IsA(a, Bitmapset));
|
||||||
Assert(b == NULL || IsA(b, Bitmapset));
|
Assert(b == NULL || IsA(b, Bitmapset));
|
||||||
@ -1105,6 +1175,13 @@ bms_join(Bitmapset *a, Bitmapset *b)
|
|||||||
return b;
|
return b;
|
||||||
if (b == NULL)
|
if (b == NULL)
|
||||||
return a;
|
return a;
|
||||||
|
|
||||||
|
#ifdef REALLOCATE_BITMAPSETS
|
||||||
|
a = (Bitmapset *) palloc(BITMAPSET_SIZE(tmp->nwords));
|
||||||
|
memcpy(a, tmp, BITMAPSET_SIZE(tmp->nwords));
|
||||||
|
pfree(tmp);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Identify shorter and longer input; use longer one as result */
|
/* Identify shorter and longer input; use longer one as result */
|
||||||
if (a->nwords < b->nwords)
|
if (a->nwords < b->nwords)
|
||||||
{
|
{
|
||||||
|
@ -335,6 +335,12 @@
|
|||||||
*/
|
*/
|
||||||
/* #define COPY_PARSE_PLAN_TREES */
|
/* #define COPY_PARSE_PLAN_TREES */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define this to force Bitmapset reallocation on each modification. Helps
|
||||||
|
* to find hangling pointers to Bitmapset's.
|
||||||
|
*/
|
||||||
|
/* #define REALLOCATE_BITMAPSETS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define this to force all parse and plan trees to be passed through
|
* Define this to force all parse and plan trees to be passed through
|
||||||
* outfuncs.c/readfuncs.c, to facilitate catching errors and omissions in
|
* outfuncs.c/readfuncs.c, to facilitate catching errors and omissions in
|
||||||
|
Loading…
x
Reference in New Issue
Block a user