v1-0001-tidstore.c-introduce-TidStoreIsMemberMulti.patch

application/x-patch

Filename: v1-0001-tidstore.c-introduce-TidStoreIsMemberMulti.patch
Type: application/x-patch
Part: 1
Message: Batch TIDs lookup in ambulkdelete

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 v1-0001
Subject: tidstore.c: introduce TidStoreIsMemberMulti.
File+
src/backend/access/common/tidstore.c 52 11
src/include/access/tidstore.h 2 0
From 236764cdfc211e04e9404ee8a38bd0d4fac9b823 Mon Sep 17 00:00:00 2001
From: Masahiko Sawada <sawada.mshk@gmail.com>
Date: Mon, 21 Apr 2025 22:40:57 -0700
Subject: [PATCH v1 1/3] tidstore.c: introduce TidStoreIsMemberMulti.

Author:
Reviewed-by:
Discussion: https://postgr.es/m/
Backpatch-through:
---
 src/backend/access/common/tidstore.c | 63 +++++++++++++++++++++++-----
 src/include/access/tidstore.h        |  2 +
 2 files changed, 54 insertions(+), 11 deletions(-)

diff --git a/src/backend/access/common/tidstore.c b/src/backend/access/common/tidstore.c
index 5bd75fb499c..c3ee9db30cc 100644
--- a/src/backend/access/common/tidstore.c
+++ b/src/backend/access/common/tidstore.c
@@ -416,20 +416,11 @@ TidStoreSetBlockOffsets(TidStore *ts, BlockNumber blkno, OffsetNumber *offsets,
 		local_ts_set(ts->tree.local, blkno, page);
 }
 
-/* Return true if the given TID is present in the TidStore */
-bool
-TidStoreIsMember(TidStore *ts, ItemPointer tid)
+static pg_attribute_always_inline int
+tidstore_is_member_page(BlocktableEntry *page, OffsetNumber off)
 {
 	int			wordnum;
 	int			bitnum;
-	BlocktableEntry *page;
-	BlockNumber blk = ItemPointerGetBlockNumber(tid);
-	OffsetNumber off = ItemPointerGetOffsetNumber(tid);
-
-	if (TidStoreIsShared(ts))
-		page = shared_ts_find(ts->tree.shared, blk);
-	else
-		page = local_ts_find(ts->tree.local, blk);
 
 	/* no entry for the blk */
 	if (page == NULL)
@@ -458,6 +449,56 @@ TidStoreIsMember(TidStore *ts, ItemPointer tid)
 	}
 }
 
+/* Return true if the given TID is present in the TidStore */
+bool
+TidStoreIsMember(TidStore *ts, ItemPointer tid)
+{
+	BlocktableEntry *page;
+	BlockNumber blk = ItemPointerGetBlockNumber(tid);
+	OffsetNumber off = ItemPointerGetOffsetNumber(tid);
+
+	if (TidStoreIsShared(ts))
+		page = shared_ts_find(ts->tree.shared, blk);
+	else
+		page = local_ts_find(ts->tree.local, blk);
+
+	return tidstore_is_member_page(page, off);
+}
+
+/*
+ * Batched operation of TidStoreIsMember().
+ */
+int
+TidStoreIsMemberMulti(TidStore *ts, ItemPointer tids, int ntids, bool *ismembers)
+{
+	BlocktableEntry *page = NULL;
+	BlockNumber last_blk = InvalidBlockNumber;
+	int		nmembers = 0;
+
+	for (int i = 0; i < ntids; i++)
+	{
+		ItemPointer	tid = &(tids[i]);
+		BlockNumber	blk = ItemPointerGetBlockNumber(tid);
+		OffsetNumber off = ItemPointerGetOffsetNumber(tid);
+
+		if (blk != last_blk)
+		{
+			if (TidStoreIsShared(ts))
+				page = shared_ts_find(ts->tree.shared, blk);
+			else
+				page = local_ts_find(ts->tree.local, blk);
+		}
+
+		ismembers[i] = tidstore_is_member_page(page, off);
+		if (ismembers[i])
+			nmembers++;
+
+		last_blk = blk;
+	}
+
+	return nmembers;
+}
+
 /*
  * Prepare to iterate through a TidStore.
  *
diff --git a/src/include/access/tidstore.h b/src/include/access/tidstore.h
index 041091df278..c3545d3d0fd 100644
--- a/src/include/access/tidstore.h
+++ b/src/include/access/tidstore.h
@@ -41,6 +41,8 @@ extern void TidStoreDestroy(TidStore *ts);
 extern void TidStoreSetBlockOffsets(TidStore *ts, BlockNumber blkno, OffsetNumber *offsets,
 									int num_offsets);
 extern bool TidStoreIsMember(TidStore *ts, ItemPointer tid);
+extern int TidStoreIsMemberMulti(TidStore *ts, ItemPointer tids, int ntids,
+								 bool *ismembers);
 extern TidStoreIter *TidStoreBeginIterate(TidStore *ts);
 extern TidStoreIterResult *TidStoreIterateNext(TidStoreIter *iter);
 extern int	TidStoreGetBlockOffsets(TidStoreIterResult *result,
-- 
2.43.5