Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+91-95
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)