]> granicus.if.org Git - postgresql/commitdiff
In bms_add_member(), use repalloc() if the bms needs to be enlarged.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 30 Sep 2013 13:37:00 +0000 (16:37 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 30 Sep 2013 13:54:03 +0000 (16:54 +0300)
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.

src/backend/nodes/bitmapset.c

index b18b7a50f1cc687e8f61b81eb069a4c6e322602c..540db16048c9bf08cc38411c6580ddfaf9610d35 100644 (file)
@@ -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;
 }