aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/lib/knapsack.c5
-rw-r--r--src/backend/nodes/bitmapset.c44
-rw-r--r--src/include/nodes/bitmapset.h1
3 files changed, 46 insertions, 4 deletions
diff --git a/src/backend/lib/knapsack.c b/src/backend/lib/knapsack.c
index 13d800718f0..439da1ad70d 100644
--- a/src/backend/lib/knapsack.c
+++ b/src/backend/lib/knapsack.c
@@ -89,10 +89,7 @@ DiscreteKnapsack(int max_weight, int num_items,
{
/* copy sets[ow] to sets[j] without realloc */
if (j != ow)
- {
- sets[j] = bms_del_members(sets[j], sets[j]);
- sets[j] = bms_add_members(sets[j], sets[ow]);
- }
+ sets[j] = bms_replace_members(sets[j], sets[ow]);
sets[j] = bms_add_member(sets[j], i);
diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c
index b0f908f978f..65805d45277 100644
--- a/src/backend/nodes/bitmapset.c
+++ b/src/backend/nodes/bitmapset.c
@@ -977,6 +977,50 @@ bms_add_members(Bitmapset *a, const Bitmapset *b)
}
/*
+ * bms_replace_members
+ * Remove all existing members from 'a' and repopulate the set with members
+ * from 'b', recycling 'a', when possible.
+ */
+Bitmapset *
+bms_replace_members(Bitmapset *a, const Bitmapset *b)
+{
+ int i;
+
+ Assert(bms_is_valid_set(a));
+ Assert(bms_is_valid_set(b));
+
+ if (a == NULL)
+ return bms_copy(b);
+ if (b == NULL)
+ {
+ pfree(a);
+ return NULL;
+ }
+
+ if (a->nwords < b->nwords)
+ a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(b->nwords));
+
+ i = 0;
+ do
+ {
+ a->words[i] = b->words[i];
+ } while (++i < b->nwords);
+
+ a->nwords = b->nwords;
+
+#ifdef REALLOCATE_BITMAPSETS
+
+ /*
+ * There's no guarantee that the repalloc returned a new pointer, so copy
+ * and free unconditionally here.
+ */
+ a = bms_copy_and_free(a);
+#endif
+
+ return a;
+}
+
+/*
* bms_add_range
* Add members in the range of 'lower' to 'upper' to the set.
*
diff --git a/src/include/nodes/bitmapset.h b/src/include/nodes/bitmapset.h
index efc8890ce61..906e8dcc157 100644
--- a/src/include/nodes/bitmapset.h
+++ b/src/include/nodes/bitmapset.h
@@ -109,6 +109,7 @@ extern BMS_Membership bms_membership(const Bitmapset *a);
extern Bitmapset *bms_add_member(Bitmapset *a, int x);
extern Bitmapset *bms_del_member(Bitmapset *a, int x);
extern Bitmapset *bms_add_members(Bitmapset *a, const Bitmapset *b);
+extern Bitmapset *bms_replace_members(Bitmapset *a, const Bitmapset *b);
extern Bitmapset *bms_add_range(Bitmapset *a, int lower, int upper);
extern Bitmapset *bms_int_members(Bitmapset *a, const Bitmapset *b);
extern Bitmapset *bms_del_members(Bitmapset *a, const Bitmapset *b);