aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/heap/heapam.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-04-21 18:24:26 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-04-21 18:24:26 +0000
commit37fa3b6c89abc05f8c4691440a27427db3a6e03b (patch)
tree3a1ddb224fee306bab8ca6282b1fcfd9e7692975 /src/backend/access/heap/heapam.c
parent95a03e9cdf7e0e33c2655dd20d2b64db191f3a21 (diff)
downloadpostgresql-37fa3b6c89abc05f8c4691440a27427db3a6e03b.tar.gz
postgresql-37fa3b6c89abc05f8c4691440a27427db3a6e03b.zip
Tweak indexscan and seqscan code to arrange that steps from one page to
the next are handled by ReleaseAndReadBuffer rather than separate ReleaseBuffer and ReadBuffer calls. This cuts the number of acquisitions of the BufMgrLock by a factor of 2 (possibly more, if an indexscan happens to pull successive rows from the same heap page). Unfortunately this doesn't seem enough to get us out of the recently discussed context-switch storm problem, but it's surely worth doing anyway.
Diffstat (limited to 'src/backend/access/heap/heapam.c')
-rw-r--r--src/backend/access/heap/heapam.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 695ef36b509..bff84588fc2 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.164 2004/04/01 21:28:43 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.165 2004/04/21 18:24:23 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -889,6 +889,28 @@ heap_fetch(Relation relation,
bool keep_buf,
PgStat_Info *pgstat_info)
{
+ /* Assume *userbuf is undefined on entry */
+ *userbuf = InvalidBuffer;
+ return heap_release_fetch(relation, snapshot, tuple,
+ userbuf, keep_buf, pgstat_info);
+}
+
+/*
+ * heap_release_fetch - retrieve tuple with given tid
+ *
+ * This has the same API as heap_fetch except that if *userbuf is not
+ * InvalidBuffer on entry, that buffer will be released before reading
+ * the new page. This saves a separate ReleaseBuffer step and hence
+ * one entry into the bufmgr when looping through multiple fetches.
+ */
+bool
+heap_release_fetch(Relation relation,
+ Snapshot snapshot,
+ HeapTuple tuple,
+ Buffer *userbuf,
+ bool keep_buf,
+ PgStat_Info *pgstat_info)
+{
ItemPointer tid = &(tuple->t_self);
ItemId lp;
Buffer buffer;
@@ -898,9 +920,10 @@ heap_fetch(Relation relation,
/*
* get the buffer from the relation descriptor. Note that this does a
- * buffer pin.
+ * buffer pin, and releases the old *userbuf if not InvalidBuffer.
*/
- buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
+ buffer = ReleaseAndReadBuffer(*userbuf, relation,
+ ItemPointerGetBlockNumber(tid));
if (!BufferIsValid(buffer))
elog(ERROR, "ReadBuffer(\"%s\", %lu) failed",