v12-0002-Adjust-bms_int_members-so-that-it-shortens-the-l.patch

application/octet-stream

Filename: v12-0002-Adjust-bms_int_members-so-that-it-shortens-the-l.patch
Type: application/octet-stream
Part: 1
Message: Re: [PoC] Reducing planning time when tables have many partitions

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch v12-0002
Subject: Adjust bms_int_members so that it shortens the left input
File+
src/backend/nodes/bitmapset.c 10 2
From 80e1aa62c5217eef9cd4c6b6a7c7ef7a5367eac1 Mon Sep 17 00:00:00 2001
From: David Rowley <dgrowley@gmail.com>
Date: Thu, 1 Dec 2022 20:36:10 +1300
Subject: [PATCH v12 2/4] Adjust bms_int_members so that it shortens the left
 input

Prior to this change, if the left input to bms_int_members had fewer
Bitmapwords than the right input, the additional words in the left input
would be zeroed.  Doing things this why only really makes sense if we
expect to add additional words to the resulting bitmap set again later.
Seemingly, most of our use cases don't add to the resulting Bitmapset,
in fact, many cases are performing bms_int_members in a loop which is
likely to even further increase the amount of all zero words in the set.

Leaving these zero trailing words in place can cause inefficiencies in
functions such as bms_is_empty and loops which loop over a set using
bms_next_member when the set is left with a large number of trailing
words.

If there are use cases which need to add additional words again, then,
repalloc has to do very little processing when the requested allocation
size is <= the actual allocation size.  Both AllocSetRealloc and
GenerationRealloc simply just return the input pointer again.  If there
are any cases where we do increase the size of the set again, then this
just shifts the zeroing of the additional words until then.

We could give bms_del_members() and bms_difference similar treatment, but
that would require additional code to record the last non-zero word after
masking out the members being deleted.  That seems less worthwhile as it
will add cost when we're unable to trim down the number of words.
---
 src/backend/nodes/bitmapset.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c
index 98660524ad..b13b4c378f 100644
--- a/src/backend/nodes/bitmapset.c
+++ b/src/backend/nodes/bitmapset.c
@@ -920,8 +920,16 @@ bms_int_members(Bitmapset *a, const Bitmapset *b)
 	shortlen = Min(a->nwords, b->nwords);
 	for (i = 0; i < shortlen; i++)
 		a->words[i] &= b->words[i];
-	for (; i < a->nwords; i++)
-		a->words[i] = 0;
+
+	/*
+	 * We simply shorten the left input to both remove the need to zero the
+	 * trailing words and also to reduce the required processing if this
+	 * function is being called in a loop.  If more words are required later
+	 * then AllocSetRealloc is likely not going to have to work very hard if
+	 * the new requested size is >= the actual size of the allocation.
+	 */
+	a->nwords = shortlen;
+
 	return a;
 }
 
-- 
2.35.3.windows.1