v7-0004-Add-heapgettup-helpers.patch
text/x-patch
Filename: v7-0004-Add-heapgettup-helpers.patch
Type: text/x-patch
Part: 3
Message:
Re: heapgettup refactoring
Patch
Format: format-patch
Series: patch v7-0004
Subject: Add heapgettup() helpers
| File | + | − |
|---|---|---|
| src/backend/access/heap/heapam.c | 79 | 31 |
From c0d7155fb0af55295b3bcd598c083b4690c538dd Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Tue, 10 Jan 2023 14:06:56 -0500
Subject: [PATCH v7 4/6] Add heapgettup() helpers
Add heapgettup_start_page() and heapgettup_continue_page(), helper
functions for heapgettup().
---
src/backend/access/heap/heapam.c | 110 ++++++++++++++++++++++---------
1 file changed, 79 insertions(+), 31 deletions(-)
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 4e238d9558..223bb1d5d3 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -545,6 +545,83 @@ heapgettup_initial_block(HeapScanDesc scan, ScanDirection dir)
return scan->rs_nblocks - 1;
}
+
+/*
+ * heapgettup_start_page - helper for heapgettup()
+ *
+ * Given a scan descriptor with a valid buffer referenced in rs_cbuf containing
+ * a block which we have yet to scan, set our lineoff at the tuple we will
+ * start with and our linesleft to the number of tuples in the page. Return the
+ * page associated with that buffer.
+ */
+static inline Page
+heapgettup_start_page(HeapScanDesc scan, ScanDirection dir, int *linesleft,
+ OffsetNumber *lineoff)
+{
+ Page page;
+
+ Assert(scan->rs_inited);
+ Assert(BufferIsValid(scan->rs_cbuf));
+
+ /* Caller is responsible for ensuring buffer is locked if needed */
+ page = BufferGetPage(scan->rs_cbuf);
+
+ TestForOldSnapshot(scan->rs_base.rs_snapshot, scan->rs_base.rs_rd, page);
+
+ *linesleft = PageGetMaxOffsetNumber((Page) page) - FirstOffsetNumber + 1;
+
+ if (ScanDirectionIsForward(dir))
+ *lineoff = FirstOffsetNumber;
+ else
+ *lineoff = (OffsetNumber) (*linesleft);
+
+ /* lineoff now references the physically previous or next tid */
+ return page;
+}
+
+
+/*
+ * heapgettup_continue_page - helper for heapgettup()
+ *
+ * Given a scan descriptor with a valid buffer referenced in rs_cbuf containing
+ * a block from which we have already fetched some tuples, set the lineoff to
+ * the start of the next tuple to fetch and update linesleft. Return the page
+ * associated with that buffer.
+ */
+static inline Page
+heapgettup_continue_page(HeapScanDesc scan, ScanDirection dir, int *linesleft,
+ OffsetNumber *lineoff)
+{
+ Page page;
+
+ Assert(scan->rs_inited);
+ Assert(BufferIsValid(scan->rs_cbuf));
+
+ /* Caller is responsible for ensuring buffer is locked if needed */
+ page = BufferGetPage(scan->rs_cbuf);
+
+ TestForOldSnapshot(scan->rs_base.rs_snapshot, scan->rs_base.rs_rd, page);
+
+ if (ScanDirectionIsForward(dir))
+ {
+ *lineoff = OffsetNumberNext(scan->rs_cindex);
+ *linesleft = PageGetMaxOffsetNumber(page) - (*lineoff) + 1;
+ }
+ else
+ {
+ /*
+ * The previous returned tuple may have been vacuumed since the
+ * previous scan when we use a non-MVCC snapshot, so we must
+ * re-establish the lineoff <= PageGetMaxOffsetNumber(page) invariant
+ */
+ *lineoff = Min(PageGetMaxOffsetNumber(page), OffsetNumberPrev(scan->rs_cindex));
+ *linesleft = *lineoff;
+ }
+
+ /* lineoff now references the physically previous or next tid */
+ return page;
+}
+
/* ----------------
* heapgettup - fetch next heap tuple
*
@@ -605,43 +682,14 @@ heapgettup(HeapScanDesc scan,
heapgetpage((TableScanDesc) scan, block);
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
- page = BufferGetPage(scan->rs_cbuf);
- TestForOldSnapshot(scan->rs_base.rs_snapshot, scan->rs_base.rs_rd,
- page);
-
- linesleft = PageGetMaxOffsetNumber(page) - FirstOffsetNumber + 1;
-
- if (ScanDirectionIsForward(dir))
- lineoff = FirstOffsetNumber;
- else
- lineoff = (OffsetNumber) linesleft;
+ page = heapgettup_start_page(scan, dir, &linesleft, &lineoff);
}
else
{
block = scan->rs_cblock;
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
- page = BufferGetPage(scan->rs_cbuf);
- TestForOldSnapshot(scan->rs_base.rs_snapshot, scan->rs_base.rs_rd, page);
-
- if (ScanDirectionIsForward(dir))
- {
- lineoff = OffsetNumberNext(scan->rs_cindex);
- linesleft = PageGetMaxOffsetNumber(page) - lineoff + 1;
- }
- else
- {
- /*
- * The previous returned tuple may have been vacuumed since the
- * previous scan when we use a non-MVCC snapshot, so we must
- * re-establish the lineoff <= PageGetMaxOffsetNumber(page)
- * invariant
- */
- lineoff =
- Min(PageGetMaxOffsetNumber(page),
- OffsetNumberPrev(scan->rs_cindex));
- linesleft = lineoff;
- }
+ page = heapgettup_continue_page(scan, dir, &linesleft, &lineoff);
}
--
2.37.2