Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3a4a353

Browse files
committed
Secondary refactor of heap scanning functions
Similar to 44086b0, refactor heap scanning functions to be more suitable for the read stream API. Author: Melanie Plageman Discussion: https://postgr.es/m/CAAKRu_YtXJiYKQvb5JsA2SkwrsizYLugs4sSOZh3EAjKUg=gEQ@mail.gmail.com
1 parent 2a217c3 commit 3a4a353

File tree

2 files changed

+55
-50
lines changed

2 files changed

+55
-50
lines changed

src/backend/access/heap/heapam.c

Lines changed: 54 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ static Bitmapset *HeapDetermineColumnsInfo(Relation relation,
8383
static bool heap_acquire_tuplock(Relation relation, ItemPointer tid,
8484
LockTupleMode mode, LockWaitPolicy wait_policy,
8585
bool *have_tuple_lock);
86+
static inline BlockNumber heapgettup_advance_block(HeapScanDesc scan,
87+
BlockNumber block,
88+
ScanDirection dir);
89+
static pg_noinline BlockNumber heapgettup_initial_block(HeapScanDesc scan,
90+
ScanDirection dir);
8691
static void compute_new_xmax_infomask(TransactionId xmax, uint16 old_infomask,
8792
uint16 old_infomask2, TransactionId add_to_xmax,
8893
LockTupleMode mode, bool is_update,
@@ -455,16 +460,14 @@ heap_prepare_pagescan(TableScanDesc sscan)
455460
}
456461

457462
/*
458-
* heapfetchbuf - read and pin the given MAIN_FORKNUM block number.
463+
* heap_fetch_next_buffer - read and pin the next block from MAIN_FORKNUM.
459464
*
460-
* Read the specified block of the scan relation into a buffer and pin that
461-
* buffer before saving it in the scan descriptor.
465+
* Read the next block of the scan relation into a buffer and pin that buffer
466+
* before saving it in the scan descriptor.
462467
*/
463468
static inline void
464-
heapfetchbuf(HeapScanDesc scan, BlockNumber block)
469+
heap_fetch_next_buffer(HeapScanDesc scan, ScanDirection dir)
465470
{
466-
Assert(block < scan->rs_nblocks);
467-
468471
/* release previous scan buffer, if any */
469472
if (BufferIsValid(scan->rs_cbuf))
470473
{
@@ -479,10 +482,25 @@ heapfetchbuf(HeapScanDesc scan, BlockNumber block)
479482
*/
480483
CHECK_FOR_INTERRUPTS();
481484

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;
485+
if (unlikely(!scan->rs_inited))
486+
{
487+
scan->rs_cblock = heapgettup_initial_block(scan, dir);
488+
489+
/* ensure rs_cbuf is invalid when we get InvalidBlockNumber */
490+
Assert(scan->rs_cblock != InvalidBlockNumber ||
491+
!BufferIsValid(scan->rs_cbuf));
492+
493+
scan->rs_inited = true;
494+
}
495+
else
496+
scan->rs_cblock = heapgettup_advance_block(scan, scan->rs_cblock,
497+
dir);
498+
499+
/* read block if valid */
500+
if (BlockNumberIsValid(scan->rs_cblock))
501+
scan->rs_cbuf = ReadBufferExtended(scan->rs_base.rs_rd, MAIN_FORKNUM,
502+
scan->rs_cblock, RBM_NORMAL,
503+
scan->rs_strategy);
486504
}
487505

488506
/*
@@ -492,7 +510,7 @@ heapfetchbuf(HeapScanDesc scan, BlockNumber block)
492510
* occur with empty tables and in parallel scans when parallel workers get all
493511
* of the pages before we can get a chance to get our first page.
494512
*/
495-
static BlockNumber
513+
static pg_noinline BlockNumber
496514
heapgettup_initial_block(HeapScanDesc scan, ScanDirection dir)
497515
{
498516
Assert(!scan->rs_inited);
@@ -619,7 +637,7 @@ heapgettup_continue_page(HeapScanDesc scan, ScanDirection dir, int *linesleft,
619637
}
620638

621639
/*
622-
* heapgettup_advance_block - helper for heapgettup() and heapgettup_pagemode()
640+
* heapgettup_advance_block - helper for heap_fetch_next_buffer()
623641
*
624642
* Given the current block number, the scan direction, and various information
625643
* contained in the scan descriptor, calculate the BlockNumber to scan next
@@ -730,23 +748,13 @@ heapgettup(HeapScanDesc scan,
730748
ScanKey key)
731749
{
732750
HeapTuple tuple = &(scan->rs_ctup);
733-
BlockNumber block;
734751
Page page;
735752
OffsetNumber lineoff;
736753
int linesleft;
737754

738-
if (unlikely(!scan->rs_inited))
739-
{
740-
block = heapgettup_initial_block(scan, dir);
741-
/* ensure rs_cbuf is invalid when we get InvalidBlockNumber */
742-
Assert(block != InvalidBlockNumber || !BufferIsValid(scan->rs_cbuf));
743-
scan->rs_inited = true;
744-
}
745-
else
755+
if (likely(scan->rs_inited))
746756
{
747757
/* continue from previously returned page/tuple */
748-
block = scan->rs_cblock;
749-
750758
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
751759
page = heapgettup_continue_page(scan, dir, &linesleft, &lineoff);
752760
goto continue_page;
@@ -756,9 +764,16 @@ heapgettup(HeapScanDesc scan,
756764
* advance the scan until we find a qualifying tuple or run out of stuff
757765
* to scan
758766
*/
759-
while (block != InvalidBlockNumber)
767+
while (true)
760768
{
761-
heapfetchbuf(scan, block);
769+
heap_fetch_next_buffer(scan, dir);
770+
771+
/* did we run out of blocks to scan? */
772+
if (!BufferIsValid(scan->rs_cbuf))
773+
break;
774+
775+
Assert(BufferGetBlockNumber(scan->rs_cbuf) == scan->rs_cblock);
776+
762777
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
763778
page = heapgettup_start_page(scan, dir, &linesleft, &lineoff);
764779
continue_page:
@@ -780,7 +795,7 @@ heapgettup(HeapScanDesc scan,
780795

781796
tuple->t_data = (HeapTupleHeader) PageGetItem(page, lpp);
782797
tuple->t_len = ItemIdGetLength(lpp);
783-
ItemPointerSet(&(tuple->t_self), block, lineoff);
798+
ItemPointerSet(&(tuple->t_self), scan->rs_cblock, lineoff);
784799

785800
visible = HeapTupleSatisfiesVisibility(tuple,
786801
scan->rs_base.rs_snapshot,
@@ -810,9 +825,6 @@ heapgettup(HeapScanDesc scan,
810825
* it's time to move to the next.
811826
*/
812827
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
813-
814-
/* get the BlockNumber to scan next */
815-
block = heapgettup_advance_block(scan, block, dir);
816828
}
817829

818830
/* end of scan */
@@ -832,9 +844,9 @@ heapgettup(HeapScanDesc scan,
832844
*
833845
* The internal logic is much the same as heapgettup's too, but there are some
834846
* differences: we do not take the buffer content lock (that only needs to
835-
* happen inside heapgetpage), and we iterate through just the tuples listed
836-
* in rs_vistuples[] rather than all tuples on the page. Notice that
837-
* lineindex is 0-based, where the corresponding loop variable lineoff in
847+
* happen inside heap_prepare_pagescan), and we iterate through just the
848+
* tuples listed in rs_vistuples[] rather than all tuples on the page. Notice
849+
* that lineindex is 0-based, where the corresponding loop variable lineoff in
838850
* heapgettup is 1-based.
839851
* ----------------
840852
*/
@@ -845,22 +857,13 @@ heapgettup_pagemode(HeapScanDesc scan,
845857
ScanKey key)
846858
{
847859
HeapTuple tuple = &(scan->rs_ctup);
848-
BlockNumber block;
849860
Page page;
850861
int lineindex;
851862
int linesleft;
852863

853-
if (unlikely(!scan->rs_inited))
854-
{
855-
block = heapgettup_initial_block(scan, dir);
856-
/* ensure rs_cbuf is invalid when we get InvalidBlockNumber */
857-
Assert(block != InvalidBlockNumber || !BufferIsValid(scan->rs_cbuf));
858-
scan->rs_inited = true;
859-
}
860-
else
864+
if (likely(scan->rs_inited))
861865
{
862866
/* continue from previously returned page/tuple */
863-
block = scan->rs_cblock; /* current page */
864867
page = BufferGetPage(scan->rs_cbuf);
865868

866869
lineindex = scan->rs_cindex + dir;
@@ -877,10 +880,15 @@ heapgettup_pagemode(HeapScanDesc scan,
877880
* advance the scan until we find a qualifying tuple or run out of stuff
878881
* to scan
879882
*/
880-
while (block != InvalidBlockNumber)
883+
while (true)
881884
{
882-
/* read the page */
883-
heapfetchbuf(scan, block);
885+
heap_fetch_next_buffer(scan, dir);
886+
887+
/* did we run out of blocks to scan? */
888+
if (!BufferIsValid(scan->rs_cbuf))
889+
break;
890+
891+
Assert(BufferGetBlockNumber(scan->rs_cbuf) == scan->rs_cblock);
884892

885893
/* prune the page and determine visible tuple offsets */
886894
heap_prepare_pagescan((TableScanDesc) scan);
@@ -902,7 +910,7 @@ heapgettup_pagemode(HeapScanDesc scan,
902910

903911
tuple->t_data = (HeapTupleHeader) PageGetItem(page, lpp);
904912
tuple->t_len = ItemIdGetLength(lpp);
905-
ItemPointerSet(&(tuple->t_self), block, lineoff);
913+
ItemPointerSet(&(tuple->t_self), scan->rs_cblock, lineoff);
906914

907915
/* skip any tuples that don't match the scan key */
908916
if (key != NULL &&
@@ -913,9 +921,6 @@ heapgettup_pagemode(HeapScanDesc scan,
913921
scan->rs_cindex = lineindex;
914922
return;
915923
}
916-
917-
/* get the BlockNumber to scan next */
918-
block = heapgettup_advance_block(scan, block, dir);
919924
}
920925

921926
/* end of scan */

src/backend/access/heap/heapam_handler.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2489,7 +2489,7 @@ heapam_scan_sample_next_tuple(TableScanDesc scan, SampleScanState *scanstate,
24892489
visible = SampleHeapTupleVisible(scan, hscan->rs_cbuf,
24902490
tuple, tupoffset);
24912491

2492-
/* in pagemode, heapgetpage did this for us */
2492+
/* in pagemode, heap_prepare_pagescan did this for us */
24932493
if (!pagemode)
24942494
HeapCheckForSerializableConflictOut(visible, scan->rs_rd, tuple,
24952495
hscan->rs_cbuf, scan->rs_snapshot);

0 commit comments

Comments
 (0)