v16-0007-Add-UnlockBufferGetLSN-utility-function.patch

application/octet-stream

Filename: v16-0007-Add-UnlockBufferGetLSN-utility-function.patch
Type: application/octet-stream
Part: 14
Message: Re: index prefetching

Patch

Format: format-patch
Series: patch v16-0007
Subject: Add UnlockBufferGetLSN utility function.
File+
src/backend/access/index/indexbatch.c 1 11
src/backend/storage/buffer/bufmgr.c 47 0
src/include/storage/bufmgr.h 1 0
From 7e78a9867214dd2a6134972476de265688355659 Mon Sep 17 00:00:00 2001
From: Peter Geoghegan <pg@bowt.ie>
Date: Tue, 17 Mar 2026 13:25:12 -0400
Subject: [PATCH v16 07/17] Add UnlockBufferGetLSN utility function.

This combines the functionality of BufferGetLSNAtomic() with
UnlockReleaseBuffer, with the option of not releasing buffer pin.
---
 src/include/storage/bufmgr.h          |  1 +
 src/backend/access/index/indexbatch.c | 12 +------
 src/backend/storage/buffer/bufmgr.c   | 47 +++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index 4017896f9..408d76c56 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -253,6 +253,7 @@ extern void WaitReadBuffers(ReadBuffersOperation *operation);
 
 extern void ReleaseBuffer(Buffer buffer);
 extern void UnlockReleaseBuffer(Buffer buffer);
+extern XLogRecPtr UnlockBufferGetLSN(Buffer buffer, bool release);
 extern bool BufferIsLockedByMe(Buffer buffer);
 extern bool BufferIsLockedByMeInMode(Buffer buffer, BufferLockMode mode);
 extern bool BufferIsDirty(Buffer buffer);
diff --git a/src/backend/access/index/indexbatch.c b/src/backend/access/index/indexbatch.c
index 007fd03dd..40c89a40c 100644
--- a/src/backend/access/index/indexbatch.c
+++ b/src/backend/access/index/indexbatch.c
@@ -562,17 +562,7 @@ indexam_util_batch_unlock(IndexScanDesc scan, IndexScanBatch batch, Buffer buf)
 		 * Non-immediate-unguard scans retain the pin; the table AM will call
 		 * amunguardbatch to drop the interlock when ready.
 		 */
-		batch->lsn = BufferGetLSNAtomic(buf);
-		if (scan->batchImmediateUnguard)
-		{
-			/* drop both the lock and the pin */
-			UnlockReleaseBuffer(buf);
-		}
-		else
-		{
-			/* just drop the lock (hold on to interlock pin) */
-			UnlockBuffer(buf);
-		}
+		batch->lsn = UnlockBufferGetLSN(buf, scan->batchImmediateUnguard);
 	}
 	else
 	{
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 00bc60952..2a95517a3 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -5525,6 +5525,53 @@ UnlockReleaseBuffer(Buffer buffer)
 	ReleaseBuffer(buffer);
 }
 
+/*
+ * UnlockBufferGetLSN
+ *		Read a buffer's LSN, then unlock the buffer.  Optionally release the
+ *		pin too.
+ *
+ * This combines the functionality of BufferGetLSNAtomic() with
+ * UnlockReleaseBuffer, with the option of not releasing buffer pin.
+ *
+ * Used to unlock a buffer lock (and possibly to release its pin) when held on
+ * an index page.  This is needed frequently enough to justify specialization.
+ */
+XLogRecPtr
+UnlockBufferGetLSN(Buffer buffer, bool release)
+{
+	BufferDesc *buf_hdr;
+	Page		page;
+	XLogRecPtr	lsn;
+
+	Assert(BufferIsValid(buffer));
+	Assert(BufferIsPinned(buffer));
+
+	if (BufferIsLocal(buffer))
+	{
+		buf_hdr = GetLocalBufferDescriptor(-buffer - 1);
+		page = (Page) LocalBufHdrGetBlock(buf_hdr);
+		lsn = PageGetLSN(page);
+		if (release)
+			UnpinLocalBuffer(buffer);
+		return lsn;
+	}
+
+	buf_hdr = GetBufferDescriptor(buffer - 1);
+	page = (Page) BufHdrGetBlock(buf_hdr);
+
+#ifdef PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY
+	lsn = PageGetLSN(page);
+#else
+	lsn = BufferGetLSNAtomic(buffer);
+#endif
+
+	BufferLockUnlock(buffer, buf_hdr);
+	if (release)
+		UnpinBuffer(buf_hdr);
+
+	return lsn;
+}
+
 /*
  * IncrBufferRefCount
  *		Increment the pin count on a buffer that we have *already* pinned
-- 
2.53.0