fix_DiscreteKnapsack_v2.patch

text/plain

Filename: fix_DiscreteKnapsack_v2.patch
Type: text/plain
Part: 0
Message: Re: Strange Bitmapset manipulation in DiscreteKnapsack()

Patch

Format: unified
Series: patch v2
File+
src/backend/lib/knapsack.c 1 4
src/backend/nodes/bitmapset.c 44 0
src/include/nodes/bitmapset.h 1 0
diff --git a/src/backend/lib/knapsack.c b/src/backend/lib/knapsack.c
index 13d800718f..439da1ad70 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 b0f908f978..8be61cd081 100644
--- a/src/backend/nodes/bitmapset.c
+++ b/src/backend/nodes/bitmapset.c
@@ -976,6 +976,50 @@ bms_add_members(Bitmapset *a, const Bitmapset *b)
 	return result;
 }
 
+/*
+ * 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 efc8890ce6..906e8dcc15 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);