From 34235a295b307d3c50b2a74b20936f01b4ba76be Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Tue, 14 Mar 2000 23:52:01 +0000
Subject: [PATCH] Cache fmgr lookup data for index's getnext() function in
 IndexScanDesc, so that the fmgr lookup only has to happen once per index scan
 and not once per tuple.  Seems to save 5% or so of CPU time for an indexscan.

---
 src/backend/access/index/genam.c   |  5 ++++-
 src/backend/access/index/indexam.c | 19 +++++++++++++++----
 src/include/access/relscan.h       |  3 ++-
 3 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c
index 103f02ecc0c..1bd02f839ad 100644
--- a/src/backend/access/index/genam.c
+++ b/src/backend/access/index/genam.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.23 2000/01/26 05:55:57 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.24 2000/03/14 23:52:01 tgl Exp $
  *
  * NOTES
  *	  many of the old access method routines have been turned into
@@ -114,6 +114,9 @@ RelationGetIndexScan(Relation relation,
 	ItemPointerSetInvalid(&scan->currentMarkData);
 	ItemPointerSetInvalid(&scan->nextMarkData);
 
+	/* mark cached function lookup data invalid; it will be set on first use */
+	scan->fn_getnext.fn_oid = InvalidOid;
+
 	if (numberOfKeys > 0)
 		scan->keyData = (ScanKey) palloc(sizeof(ScanKeyData) * numberOfKeys);
 	else
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index f4f0d25768b..23356931198 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.40 2000/01/26 05:55:57 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.41 2000/03/14 23:52:01 tgl Exp $
  *
  * INTERFACE ROUTINES
  *		index_open		- open an index relation by relationId
@@ -329,17 +329,28 @@ RetrieveIndexResult
 index_getnext(IndexScanDesc scan,
 			  ScanDirection direction)
 {
-	RegProcedure procedure;
 	RetrieveIndexResult result;
 
 	SCAN_CHECKS;
-	GET_SCAN_PROCEDURE(getnext, amgettuple);
+
+	/* ----------------
+	 *	Look up the access procedure only once per scan.
+	 * ----------------
+	 */
+	if (scan->fn_getnext.fn_oid == InvalidOid)
+	{
+		RegProcedure procedure;
+
+		GET_SCAN_PROCEDURE(getnext, amgettuple);
+		fmgr_info(procedure, &scan->fn_getnext);
+	}
 
 	/* ----------------
 	 *	have the am's gettuple proc do all the work.
 	 * ----------------
 	 */
-	result = (RetrieveIndexResult) fmgr(procedure, scan, direction);
+	result = (RetrieveIndexResult)
+		(*fmgr_faddr(&scan->fn_getnext)) (scan, direction);
 
 	return result;
 }
diff --git a/src/include/access/relscan.h b/src/include/access/relscan.h
index c3101bd92f6..19e4e28631d 100644
--- a/src/include/access/relscan.h
+++ b/src/include/access/relscan.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: relscan.h,v 1.18 2000/01/26 05:57:51 momjian Exp $
+ * $Id: relscan.h,v 1.19 2000/03/14 23:52:00 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -54,6 +54,7 @@ typedef struct IndexScanDescData
 	bool		scanFromEnd;	/* restart scan at end? */
 	uint16		numberOfKeys;	/* number of key attributes */
 	ScanKey		keyData;		/* key descriptor */
+	FmgrInfo	fn_getnext;		/* cached lookup info for am's getnext fn */
 } IndexScanDescData;
 
 typedef IndexScanDescData *IndexScanDesc;
-- 
GitLab