From 6904be530a804d830d10be86e31768e6d51aa15d Mon Sep 17 00:00:00 2001
From: David Geier <geidav.pg@gmail.com>
Date: Wed, 7 Oct 2026 16:26:52 +0200
Subject: [PATCH v1] btgetbitmap() inserts TIDs in batches

Changed btgetbitmap() to collect all TIDs from a B-tree page into
an array and add them to the TIDBitmap in a single tbm_add_tuples()
call, rather than adding each TID individually. This reduces the
number of hash map lookups needed to process one page.

Also simplified the control flow by using a for loop with
_bt_first() / _bt_next() instead of nested do-while loops.
---
 src/backend/access/nbtree/nbtree.c | 37 ++++++++----------------------
 1 file changed, 9 insertions(+), 28 deletions(-)

diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index 0abdd7b49f5..90192b789cc 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -291,45 +291,26 @@ int64
 btgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
 {
 	BTScanOpaque so = (BTScanOpaque) scan->opaque;
-	int64		ntids = 0;
-	ItemPointer heapTid;
+	int64		 ntids_total = 0;
 
 	Assert(scan->heapRelation == NULL);
 
-	/* Each loop iteration performs another primitive index scan */
 	do
 	{
-		/* Fetch the first page & tuple */
-		if (_bt_first(scan, ForwardScanDirection))
+		for (bool more = _bt_first(scan, ForwardScanDirection); more; more =_bt_next(scan, ForwardScanDirection))
 		{
-			/* Save tuple ID, and continue scanning */
-			heapTid = &scan->xs_heaptid;
-			tbm_add_tuples(tbm, heapTid, 1, false);
-			ntids++;
+			ItemPointerData tids[MaxTIDsPerBTreePage];
+			int				ntids_page = 0;
 
-			for (;;)
-			{
-				/*
-				 * Advance to next tuple within page.  This is the same as the
-				 * easy case in _bt_next().
-				 */
-				if (++so->currPos.itemIndex > so->currPos.lastItem)
-				{
-					/* let _bt_next do the heavy lifting */
-					if (!_bt_next(scan, ForwardScanDirection))
-						break;
-				}
+			while (so->currPos.itemIndex <= so->currPos.lastItem)
+				tids[ntids_page++] = so->currPos.items[so->currPos.itemIndex++].heapTid;
 
-				/* Save tuple ID, and continue scanning */
-				heapTid = &so->currPos.items[so->currPos.itemIndex].heapTid;
-				tbm_add_tuples(tbm, heapTid, 1, false);
-				ntids++;
-			}
+			tbm_add_tuples(tbm, tids, ntids_page, false);
+			ntids_total += ntids_page;
 		}
-		/* Now see if we need another primitive index scan */
 	} while (so->numArrayKeys && _bt_start_prim_scan(scan));
 
-	return ntids;
+	return ntids_total;
 }
 
 /*
-- 
2.53.0

