Skip to content

Commit 7ae0ab0

Browse files
committed
Reduce code duplication between heapgettup and heapgettup_pagemode
The code to get the next block number was exactly the same between these two functions, so let's just put it into a helper function and call that from both locations. Author: Melanie Plageman Reviewed-by: Andres Freund, David Rowley Discussion: https://postgr.es/m/CAAKRu_bvkhka0CZQun28KTqhuUh5ZqY=_T8QEqZqOL02rpi2bw@mail.gmail.com
1 parent 3e577ff commit 7ae0ab0

File tree

1 file changed

+91
-95
lines changed

1 file changed

+91
-95
lines changed

src/backend/access/heap/heapam.c

Lines changed: 91 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,91 @@ heapgettup_continue_page(HeapScanDesc scan, ScanDirection dir, int *linesleft,
620620
return page;
621621
}
622622

623+
/*
624+
* heapgettup_advance_block - helper for heapgettup() and heapgettup_pagemode()
625+
*
626+
* Given the current block number, the scan direction, and various information
627+
* contained in the scan descriptor, calculate the BlockNumber to scan next
628+
* and return it. If there are no further blocks to scan, return
629+
* InvalidBlockNumber to indicate this fact to the caller.
630+
*
631+
* This should not be called to determine the initial block number -- only for
632+
* subsequent blocks.
633+
*
634+
* This also adjusts rs_numblocks when a limit has been imposed by
635+
* heap_setscanlimits().
636+
*/
637+
static inline BlockNumber
638+
heapgettup_advance_block(HeapScanDesc scan, BlockNumber block, ScanDirection dir)
639+
{
640+
if (ScanDirectionIsForward(dir))
641+
{
642+
if (scan->rs_base.rs_parallel == NULL)
643+
{
644+
block++;
645+
646+
/* wrap back to the start of the heap */
647+
if (block >= scan->rs_nblocks)
648+
block = 0;
649+
650+
/* we're done if we're back at where we started */
651+
if (block == scan->rs_startblock)
652+
return InvalidBlockNumber;
653+
654+
/* check if the limit imposed by heap_setscanlimits() is met */
655+
if (scan->rs_numblocks != InvalidBlockNumber)
656+
{
657+
if (--scan->rs_numblocks == 0)
658+
return InvalidBlockNumber;
659+
}
660+
661+
/*
662+
* Report our new scan position for synchronization purposes. We
663+
* don't do that when moving backwards, however. That would just
664+
* mess up any other forward-moving scanners.
665+
*
666+
* Note: we do this before checking for end of scan so that the
667+
* final state of the position hint is back at the start of the
668+
* rel. That's not strictly necessary, but otherwise when you run
669+
* the same query multiple times the starting position would shift
670+
* a little bit backwards on every invocation, which is confusing.
671+
* We don't guarantee any specific ordering in general, though.
672+
*/
673+
if (scan->rs_base.rs_flags & SO_ALLOW_SYNC)
674+
ss_report_location(scan->rs_base.rs_rd, block);
675+
676+
return block;
677+
}
678+
else
679+
{
680+
return table_block_parallelscan_nextpage(scan->rs_base.rs_rd,
681+
scan->rs_parallelworkerdata, (ParallelBlockTableScanDesc)
682+
scan->rs_base.rs_parallel);
683+
}
684+
}
685+
else
686+
{
687+
/* we're done if the last block is the start position */
688+
if (block == scan->rs_startblock)
689+
return InvalidBlockNumber;
690+
691+
/* check if the limit imposed by heap_setscanlimits() is met */
692+
if (scan->rs_numblocks != InvalidBlockNumber)
693+
{
694+
if (--scan->rs_numblocks == 0)
695+
return InvalidBlockNumber;
696+
}
697+
698+
/* wrap to the end of the heap when the last page was page 0 */
699+
if (block == 0)
700+
block = scan->rs_nblocks;
701+
702+
block--;
703+
704+
return block;
705+
}
706+
}
707+
623708
/* ----------------
624709
* heapgettup - fetch next heap tuple
625710
*
@@ -649,7 +734,6 @@ heapgettup(HeapScanDesc scan,
649734
HeapTuple tuple = &(scan->rs_ctup);
650735
bool backward = ScanDirectionIsBackward(dir);
651736
BlockNumber block;
652-
bool finished;
653737
Page page;
654738
OffsetNumber lineoff;
655739
int linesleft;
@@ -755,56 +839,13 @@ heapgettup(HeapScanDesc scan,
755839
*/
756840
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
757841

758-
/*
759-
* advance to next/prior page and detect end of scan
760-
*/
761-
if (backward)
762-
{
763-
finished = (block == scan->rs_startblock) ||
764-
(scan->rs_numblocks != InvalidBlockNumber ? --scan->rs_numblocks == 0 : false);
765-
if (block == 0)
766-
block = scan->rs_nblocks;
767-
block--;
768-
}
769-
else if (scan->rs_base.rs_parallel != NULL)
770-
{
771-
ParallelBlockTableScanDesc pbscan =
772-
(ParallelBlockTableScanDesc) scan->rs_base.rs_parallel;
773-
ParallelBlockTableScanWorker pbscanwork =
774-
scan->rs_parallelworkerdata;
775-
776-
block = table_block_parallelscan_nextpage(scan->rs_base.rs_rd,
777-
pbscanwork, pbscan);
778-
finished = (block == InvalidBlockNumber);
779-
}
780-
else
781-
{
782-
block++;
783-
if (block >= scan->rs_nblocks)
784-
block = 0;
785-
finished = (block == scan->rs_startblock) ||
786-
(scan->rs_numblocks != InvalidBlockNumber ? --scan->rs_numblocks == 0 : false);
787-
788-
/*
789-
* Report our new scan position for synchronization purposes. We
790-
* don't do that when moving backwards, however. That would just
791-
* mess up any other forward-moving scanners.
792-
*
793-
* Note: we do this before checking for end of scan so that the
794-
* final state of the position hint is back at the start of the
795-
* rel. That's not strictly necessary, but otherwise when you run
796-
* the same query multiple times the starting position would shift
797-
* a little bit backwards on every invocation, which is confusing.
798-
* We don't guarantee any specific ordering in general, though.
799-
*/
800-
if (scan->rs_base.rs_flags & SO_ALLOW_SYNC)
801-
ss_report_location(scan->rs_base.rs_rd, block);
802-
}
842+
/* get the BlockNumber to scan next */
843+
block = heapgettup_advance_block(scan, block, dir);
803844

804845
/*
805846
* return NULL if we've exhausted all the pages
806847
*/
807-
if (finished)
848+
if (block == InvalidBlockNumber)
808849
{
809850
if (BufferIsValid(scan->rs_cbuf))
810851
ReleaseBuffer(scan->rs_cbuf);
@@ -858,7 +899,6 @@ heapgettup_pagemode(HeapScanDesc scan,
858899
HeapTuple tuple = &(scan->rs_ctup);
859900
bool backward = ScanDirectionIsBackward(dir);
860901
BlockNumber block;
861-
bool finished;
862902
Page page;
863903
int lineindex;
864904
OffsetNumber lineoff;
@@ -949,57 +989,13 @@ heapgettup_pagemode(HeapScanDesc scan,
949989
++lineindex;
950990
}
951991

952-
/*
953-
* if we get here, it means we've exhausted the items on this page and
954-
* it's time to move to the next.
955-
*/
956-
if (backward)
957-
{
958-
finished = (block == scan->rs_startblock) ||
959-
(scan->rs_numblocks != InvalidBlockNumber ? --scan->rs_numblocks == 0 : false);
960-
if (block == 0)
961-
block = scan->rs_nblocks;
962-
block--;
963-
}
964-
else if (scan->rs_base.rs_parallel != NULL)
965-
{
966-
ParallelBlockTableScanDesc pbscan =
967-
(ParallelBlockTableScanDesc) scan->rs_base.rs_parallel;
968-
ParallelBlockTableScanWorker pbscanwork =
969-
scan->rs_parallelworkerdata;
970-
971-
block = table_block_parallelscan_nextpage(scan->rs_base.rs_rd,
972-
pbscanwork, pbscan);
973-
finished = (block == InvalidBlockNumber);
974-
}
975-
else
976-
{
977-
block++;
978-
if (block >= scan->rs_nblocks)
979-
block = 0;
980-
finished = (block == scan->rs_startblock) ||
981-
(scan->rs_numblocks != InvalidBlockNumber ? --scan->rs_numblocks == 0 : false);
982-
983-
/*
984-
* Report our new scan position for synchronization purposes. We
985-
* don't do that when moving backwards, however. That would just
986-
* mess up any other forward-moving scanners.
987-
*
988-
* Note: we do this before checking for end of scan so that the
989-
* final state of the position hint is back at the start of the
990-
* rel. That's not strictly necessary, but otherwise when you run
991-
* the same query multiple times the starting position would shift
992-
* a little bit backwards on every invocation, which is confusing.
993-
* We don't guarantee any specific ordering in general, though.
994-
*/
995-
if (scan->rs_base.rs_flags & SO_ALLOW_SYNC)
996-
ss_report_location(scan->rs_base.rs_rd, block);
997-
}
992+
/* get the BlockNumber to scan next */
993+
block = heapgettup_advance_block(scan, block, dir);
998994

999995
/*
1000996
* return NULL if we've exhausted all the pages
1001997
*/
1002-
if (finished)
998+
if (block == InvalidBlockNumber)
1003999
{
10041000
if (BufferIsValid(scan->rs_cbuf))
10051001
ReleaseBuffer(scan->rs_cbuf);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy