From 236764cdfc211e04e9404ee8a38bd0d4fac9b823 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada 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