From 408c97782a9dd21170622630f4c027947a09155a Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Tue, 13 Aug 2024 18:15:49 +0300
Subject: [PATCH v2 6/6] Add a small cache to Snapshot to avoid CSN lookups

Keep the status of a few recently-looked up XIDs cached in the
SnapshotData. This avoids having to go the CSN log in the common case
that the same XIDs are looked up over and over again.
---
 src/backend/utils/time/snapmgr.c | 28 +++++++++++++++++++++++++++-
 src/include/utils/snapshot.h     |  4 ++++
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c
index da82def846..e2b65e0dd5 100644
--- a/src/backend/utils/time/snapmgr.c
+++ b/src/backend/utils/time/snapmgr.c
@@ -1807,6 +1807,7 @@ RestoreSnapshot(char *start_address)
 	snapshot->whenTaken = serialized_snapshot.whenTaken;
 	snapshot->lsn = serialized_snapshot.lsn;
 	snapshot->snapshotCsn = serialized_snapshot.snapshotCsn;
+	memset(snapshot->visible_cache, 0, sizeof(snapshot->visible_cache));
 	snapshot->snapXactCompletionCount = 0;
 
 	/* Copy XIDs, if present. */
@@ -1917,12 +1918,37 @@ XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot)
 	}
 	else
 	{
-		XLogRecPtr	csn = CSNLogGetCSNByXid(xid);
+		XLogRecPtr	csn;
 
+		/* see if we have this cached */
+		for (int i = 0; i < VISIBLE_CACHE_XACTS; i++)
+		{
+			if (snapshot->visible_cache[i] == xid)
+				return true;
+		}
+		for (int i = 0; i < VISIBLE_CACHE_XACTS; i++)
+		{
+			if (snapshot->invisible_cache[i] == xid)
+				return false;
+		}
+
+		csn = CSNLogGetCSNByXid(xid);
 		if (csn != InvalidXLogRecPtr && csn <= snapshot->snapshotCsn)
+		{
+			static uint8 last = 0;
+
+			snapshot->invisible_cache[last % VISIBLE_CACHE_XACTS] = xid;
+			last++;
 			return false;
+		}
 		else
+		{
+			static uint8 last = 0;
+
+			snapshot->visible_cache[last % VISIBLE_CACHE_XACTS] = xid;
+			last++;
 			return true;
+		}
 	}
 
 	return false;
diff --git a/src/include/utils/snapshot.h b/src/include/utils/snapshot.h
index 1fda5b06f6..88cfce2ffe 100644
--- a/src/include/utils/snapshot.h
+++ b/src/include/utils/snapshot.h
@@ -188,6 +188,10 @@ typedef struct SnapshotData
 	 */
 	XLogRecPtr	snapshotCsn;
 
+#define VISIBLE_CACHE_XACTS 4
+	TransactionId visible_cache[VISIBLE_CACHE_XACTS];
+	TransactionId invisible_cache[VISIBLE_CACHE_XACTS];
+
 	bool		takenDuringRecovery;	/* recovery-shaped snapshot? */
 	bool		copied;			/* false if it's a static snapshot */
 
-- 
2.39.2

