Skip to content

Commit 44086b0

Browse files
committed
Preliminary refactor of heap scanning functions
To allow the use of the read stream API added in b5a9b18 for sequential scans on heap tables, here we make some adjustments to make that change less invasive and perhaps make the code easier to follow in the process. Here heapgetpage() gets broken into two functions: 1) The part which reads the block has now been moved into a function named heapfetchbuf(). 2) The part which performed pruning and populated the scan's rs_vistuples[] array is now moved into a new function named heap_prepare_pagescan(). The functionality provided by heap_prepare_pagescan() was only ever required by SO_ALLOW_PAGEMODE scans, so the branching that was previously done in heapgetpage() is no longer needed as we simply just don't call heap_prepare_pagescan() from heapgettup() in the refactored code. Author: Melanie Plageman Discussion: https://postgr.es/m/CAAKRu_YtXJiYKQvb5JsA2SkwrsizYLugs4sSOZh3EAjKUg=gEQ@mail.gmail.com
1 parent 85230a2 commit 44086b0

File tree

3 files changed

+75
-45
lines changed

3 files changed

+75
-45
lines changed

src/backend/access/heap/heapam.c

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -360,49 +360,28 @@ heap_setscanlimits(TableScanDesc sscan, BlockNumber startBlk, BlockNumber numBlk
360360
}
361361

362362
/*
363-
* heapgetpage - subroutine for heapgettup()
363+
* heap_prepare_pagescan - Prepare current scan page to be scanned in pagemode
364364
*
365-
* This routine reads and pins the specified page of the relation.
366-
* In page-at-a-time mode it performs additional work, namely determining
367-
* which tuples on the page are visible.
365+
* Preparation currently consists of 1. prune the scan's rs_cbuf page, and 2.
366+
* fill the rs_vistuples[] array with the OffsetNumbers of visible tuples.
368367
*/
369368
void
370-
heapgetpage(TableScanDesc sscan, BlockNumber block)
369+
heap_prepare_pagescan(TableScanDesc sscan)
371370
{
372371
HeapScanDesc scan = (HeapScanDesc) sscan;
373-
Buffer buffer;
372+
Buffer buffer = scan->rs_cbuf;
373+
BlockNumber block = scan->rs_cblock;
374374
Snapshot snapshot;
375375
Page page;
376376
int lines;
377377
int ntup;
378378
OffsetNumber lineoff;
379379
bool all_visible;
380380

381-
Assert(block < scan->rs_nblocks);
382-
383-
/* release previous scan buffer, if any */
384-
if (BufferIsValid(scan->rs_cbuf))
385-
{
386-
ReleaseBuffer(scan->rs_cbuf);
387-
scan->rs_cbuf = InvalidBuffer;
388-
}
389-
390-
/*
391-
* Be sure to check for interrupts at least once per page. Checks at
392-
* higher code levels won't be able to stop a seqscan that encounters many
393-
* pages' worth of consecutive dead tuples.
394-
*/
395-
CHECK_FOR_INTERRUPTS();
396-
397-
/* read page using selected strategy */
398-
scan->rs_cbuf = ReadBufferExtended(scan->rs_base.rs_rd, MAIN_FORKNUM, block,
399-
RBM_NORMAL, scan->rs_strategy);
400-
scan->rs_cblock = block;
401-
402-
if (!(scan->rs_base.rs_flags & SO_ALLOW_PAGEMODE))
403-
return;
381+
Assert(BufferGetBlockNumber(buffer) == block);
404382

405-
buffer = scan->rs_cbuf;
383+
/* ensure we're not accidentally being used when not in pagemode */
384+
Assert(scan->rs_base.rs_flags & SO_ALLOW_PAGEMODE);
406385
snapshot = scan->rs_base.rs_snapshot;
407386

408387
/*
@@ -475,6 +454,37 @@ heapgetpage(TableScanDesc sscan, BlockNumber block)
475454
scan->rs_ntuples = ntup;
476455
}
477456

457+
/*
458+
* heapfetchbuf - read and pin the given MAIN_FORKNUM block number.
459+
*
460+
* Read the specified block of the scan relation into a buffer and pin that
461+
* buffer before saving it in the scan descriptor.
462+
*/
463+
static inline void
464+
heapfetchbuf(HeapScanDesc scan, BlockNumber block)
465+
{
466+
Assert(block < scan->rs_nblocks);
467+
468+
/* release previous scan buffer, if any */
469+
if (BufferIsValid(scan->rs_cbuf))
470+
{
471+
ReleaseBuffer(scan->rs_cbuf);
472+
scan->rs_cbuf = InvalidBuffer;
473+
}
474+
475+
/*
476+
* Be sure to check for interrupts at least once per page. Checks at
477+
* higher code levels won't be able to stop a seqscan that encounters many
478+
* pages' worth of consecutive dead tuples.
479+
*/
480+
CHECK_FOR_INTERRUPTS();
481+
482+
/* read page using selected strategy */
483+
scan->rs_cbuf = ReadBufferExtended(scan->rs_base.rs_rd, MAIN_FORKNUM, block,
484+
RBM_NORMAL, scan->rs_strategy);
485+
scan->rs_cblock = block;
486+
}
487+
478488
/*
479489
* heapgettup_initial_block - return the first BlockNumber to scan
480490
*
@@ -748,7 +758,7 @@ heapgettup(HeapScanDesc scan,
748758
*/
749759
while (block != InvalidBlockNumber)
750760
{
751-
heapgetpage((TableScanDesc) scan, block);
761+
heapfetchbuf(scan, block);
752762
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
753763
page = heapgettup_start_page(scan, dir, &linesleft, &lineoff);
754764
continue_page:
@@ -869,7 +879,11 @@ heapgettup_pagemode(HeapScanDesc scan,
869879
*/
870880
while (block != InvalidBlockNumber)
871881
{
872-
heapgetpage((TableScanDesc) scan, block);
882+
/* read the page */
883+
heapfetchbuf(scan, block);
884+
885+
/* prune the page and determine visible tuple offsets */
886+
heap_prepare_pagescan((TableScanDesc) scan);
873887
page = BufferGetPage(scan->rs_cbuf);
874888
linesleft = scan->rs_ntuples;
875889
lineindex = ScanDirectionIsForward(dir) ? 0 : linesleft - 1;

src/backend/access/heap/heapam_handler.c

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2352,11 +2352,15 @@ heapam_scan_sample_next_block(TableScanDesc scan, SampleScanState *scanstate)
23522352
if (hscan->rs_nblocks == 0)
23532353
return false;
23542354

2355-
if (tsm->NextSampleBlock)
2355+
/* release previous scan buffer, if any */
2356+
if (BufferIsValid(hscan->rs_cbuf))
23562357
{
2357-
blockno = tsm->NextSampleBlock(scanstate, hscan->rs_nblocks);
2358-
hscan->rs_cblock = blockno;
2358+
ReleaseBuffer(hscan->rs_cbuf);
2359+
hscan->rs_cbuf = InvalidBuffer;
23592360
}
2361+
2362+
if (tsm->NextSampleBlock)
2363+
blockno = tsm->NextSampleBlock(scanstate, hscan->rs_nblocks);
23602364
else
23612365
{
23622366
/* scanning table sequentially */
@@ -2398,20 +2402,32 @@ heapam_scan_sample_next_block(TableScanDesc scan, SampleScanState *scanstate)
23982402
}
23992403
}
24002404

2405+
hscan->rs_cblock = blockno;
2406+
24012407
if (!BlockNumberIsValid(blockno))
24022408
{
2403-
if (BufferIsValid(hscan->rs_cbuf))
2404-
ReleaseBuffer(hscan->rs_cbuf);
2405-
hscan->rs_cbuf = InvalidBuffer;
2406-
hscan->rs_cblock = InvalidBlockNumber;
24072409
hscan->rs_inited = false;
2408-
24092410
return false;
24102411
}
24112412

2412-
heapgetpage(scan, blockno);
2413-
hscan->rs_inited = true;
2413+
Assert(hscan->rs_cblock < hscan->rs_nblocks);
2414+
2415+
/*
2416+
* Be sure to check for interrupts at least once per page. Checks at
2417+
* higher code levels won't be able to stop a sample scan that encounters
2418+
* many pages' worth of consecutive dead tuples.
2419+
*/
2420+
CHECK_FOR_INTERRUPTS();
2421+
2422+
/* Read page using selected strategy */
2423+
hscan->rs_cbuf = ReadBufferExtended(hscan->rs_base.rs_rd, MAIN_FORKNUM,
2424+
blockno, RBM_NORMAL, hscan->rs_strategy);
24142425

2426+
/* in pagemode, prune the page and determine visible tuple offsets */
2427+
if (hscan->rs_base.rs_flags & SO_ALLOW_PAGEMODE)
2428+
heap_prepare_pagescan(scan);
2429+
2430+
hscan->rs_inited = true;
24152431
return true;
24162432
}
24172433

@@ -2572,8 +2588,8 @@ SampleHeapTupleVisible(TableScanDesc scan, Buffer buffer,
25722588
if (scan->rs_flags & SO_ALLOW_PAGEMODE)
25732589
{
25742590
/*
2575-
* In pageatatime mode, heapgetpage() already did visibility checks,
2576-
* so just look at the info it left in rs_vistuples[].
2591+
* In pageatatime mode, heap_prepare_pagescan() already did visibility
2592+
* checks, so just look at the info it left in rs_vistuples[].
25772593
*
25782594
* We use a binary search over the known-sorted array. Note: we could
25792595
* save some effort if we insisted that NextSampleTuple select tuples

src/include/access/heapam.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ extern TableScanDesc heap_beginscan(Relation relation, Snapshot snapshot,
267267
uint32 flags);
268268
extern void heap_setscanlimits(TableScanDesc sscan, BlockNumber startBlk,
269269
BlockNumber numBlks);
270-
extern void heapgetpage(TableScanDesc sscan, BlockNumber block);
270+
extern void heap_prepare_pagescan(TableScanDesc sscan);
271271
extern void heap_rescan(TableScanDesc sscan, ScanKey key, bool set_params,
272272
bool allow_strat, bool allow_sync, bool allow_pagemode);
273273
extern void heap_endscan(TableScanDesc sscan);

0 commit comments

Comments
 (0)