Permalink
Browse files

In bms_add_member(), use repalloc() if the bms needs to be enlarged.

Previously bms_add_member() would palloc a whole-new copy of the existing
set, copy the words, and pfree the old one. repalloc() is potentially much
faster, and more importantly, this is less surprising if CurrentMemoryContext
is not the same as the context the old set is in. bms_add_member() still
allocates a new bitmapset in CurrentMemoryContext if NULL is passed as
argument, but that is a lot less likely to induce bugs.

Nicholas White.
  • Loading branch information...
1 parent 357f752 commit ee01d848f39400c8524c66944ada6fde47894978 @hlinnaka hlinnaka committed Sep 30, 2013
Showing with 9 additions and 10 deletions.
  1. +9 −10 src/backend/nodes/bitmapset.c
View
19 src/backend/nodes/bitmapset.c
@@ -632,21 +632,20 @@ bms_add_member(Bitmapset *a, int x)
return bms_make_singleton(x);
wordnum = WORDNUM(x);
bitnum = BITNUM(x);
+
+ /* enlarge the set if necessary */
if (wordnum >= a->nwords)
{
- /* Slow path: make a larger set and union the input set into it */
- Bitmapset *result;
- int nwords;
+ int oldnwords = a->nwords;
int i;
- result = bms_make_singleton(x);
- nwords = a->nwords;
- for (i = 0; i < nwords; i++)
- result->words[i] |= a->words[i];
- pfree(a);
- return result;
+ a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(wordnum + 1));
+ a->nwords = wordnum + 1;
+ /* zero out the enlarged portion */
+ for (i = oldnwords; i < a->nwords; i++)
+ a->words[i] = 0;
}
- /* Fast path: x fits in existing set */
+
a->words[wordnum] |= ((bitmapword) 1 << bitnum);
return a;
}

0 comments on commit ee01d84

Please sign in to comment.