Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitfb1a59d

Browse files
committed
Refactor heapam.c adding heapgettup_initial_block function
Here we adjust heapgettup() and heapgettup_pagemode() to move the codethat fetches the first block number to scan out into a helper function.This removes some code duplication.Author: Melanie PlagemanReviewed-by: David RowleyDiscussion:https://postgr.es/m/CAAKRu_bvkhka0CZQun28KTqhuUh5ZqY=_T8QEqZqOL02rpi2bw@mail.gmail.com
1 parent253432f commitfb1a59d

File tree

1 file changed

+102
-121
lines changed

1 file changed

+102
-121
lines changed

‎src/backend/access/heap/heapam.c

Lines changed: 102 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,67 @@ heapgetpage(TableScanDesc sscan, BlockNumber block)
483483
scan->rs_ntuples=ntup;
484484
}
485485

486+
/*
487+
* heapgettup_initial_block - return the first BlockNumber to scan
488+
*
489+
* Returns InvalidBlockNumber when there are no blocks to scan. This can
490+
* occur with empty tables and in parallel scans when parallel workers get all
491+
* of the pages before we can get a chance to get our first page.
492+
*/
493+
staticBlockNumber
494+
heapgettup_initial_block(HeapScanDescscan,ScanDirectiondir)
495+
{
496+
Assert(!scan->rs_inited);
497+
498+
/* When there are no pages to scan, return InvalidBlockNumber */
499+
if (scan->rs_nblocks==0||scan->rs_numblocks==0)
500+
returnInvalidBlockNumber;
501+
502+
if (ScanDirectionIsForward(dir))
503+
{
504+
/* serial scan */
505+
if (scan->rs_base.rs_parallel==NULL)
506+
returnscan->rs_startblock;
507+
else
508+
{
509+
/* parallel scan */
510+
table_block_parallelscan_startblock_init(scan->rs_base.rs_rd,
511+
scan->rs_parallelworkerdata,
512+
(ParallelBlockTableScanDesc)scan->rs_base.rs_parallel);
513+
514+
/* may return InvalidBlockNumber if there are no more blocks */
515+
returntable_block_parallelscan_nextpage(scan->rs_base.rs_rd,
516+
scan->rs_parallelworkerdata,
517+
(ParallelBlockTableScanDesc)scan->rs_base.rs_parallel);
518+
}
519+
}
520+
else
521+
{
522+
/* backward parallel scan not supported */
523+
Assert(scan->rs_base.rs_parallel==NULL);
524+
525+
/*
526+
* Disable reporting to syncscan logic in a backwards scan; it's not
527+
* very likely anyone else is doing the same thing at the same time,
528+
* and much more likely that we'll just bollix things for forward
529+
* scanners.
530+
*/
531+
scan->rs_base.rs_flags &= ~SO_ALLOW_SYNC;
532+
533+
/*
534+
* Start from last page of the scan. Ensure we take into account
535+
* rs_numblocks if it's been adjusted by heap_setscanlimits().
536+
*/
537+
if (scan->rs_numblocks!=InvalidBlockNumber)
538+
return (scan->rs_startblock+scan->rs_numblocks-1) %scan->rs_nblocks;
539+
540+
if (scan->rs_startblock>0)
541+
returnscan->rs_startblock-1;
542+
543+
returnscan->rs_nblocks-1;
544+
}
545+
}
546+
486547
/* ----------------
487548
*heapgettup - fetch next heap tuple
488549
*
@@ -527,38 +588,19 @@ heapgettup(HeapScanDesc scan,
527588
{
528589
if (!scan->rs_inited)
529590
{
591+
block=heapgettup_initial_block(scan,dir);
592+
530593
/*
531-
* return null immediately if relation is empty
594+
* Check if we have reached the end of the scan already. This
595+
* could happen if the table is empty or if the parallel workers
596+
* have already finished the scan before we did anything ourselves
532597
*/
533-
if (scan->rs_nblocks==0||scan->rs_numblocks==0)
598+
if (block==InvalidBlockNumber)
534599
{
535600
Assert(!BufferIsValid(scan->rs_cbuf));
536601
tuple->t_data=NULL;
537602
return;
538603
}
539-
if (scan->rs_base.rs_parallel!=NULL)
540-
{
541-
ParallelBlockTableScanDescpbscan=
542-
(ParallelBlockTableScanDesc)scan->rs_base.rs_parallel;
543-
ParallelBlockTableScanWorkerpbscanwork=
544-
scan->rs_parallelworkerdata;
545-
546-
table_block_parallelscan_startblock_init(scan->rs_base.rs_rd,
547-
pbscanwork,pbscan);
548-
549-
block=table_block_parallelscan_nextpage(scan->rs_base.rs_rd,
550-
pbscanwork,pbscan);
551-
552-
/* Other processes might have already finished the scan. */
553-
if (block==InvalidBlockNumber)
554-
{
555-
Assert(!BufferIsValid(scan->rs_cbuf));
556-
tuple->t_data=NULL;
557-
return;
558-
}
559-
}
560-
else
561-
block=scan->rs_startblock;/* first page */
562604
heapgetpage((TableScanDesc)scan,block);
563605
lineoff=FirstOffsetNumber;/* first offnum */
564606
scan->rs_inited= true;
@@ -582,60 +624,40 @@ heapgettup(HeapScanDesc scan,
582624
}
583625
else
584626
{
585-
/* backward parallel scan not supported */
586-
Assert(scan->rs_base.rs_parallel==NULL);
587-
588627
if (!scan->rs_inited)
589628
{
629+
block=heapgettup_initial_block(scan,dir);
630+
590631
/*
591-
* return null immediately if relation is empty
632+
* Check if we have reached the end of the scan already. This
633+
* could happen if the table is empty.
592634
*/
593-
if (scan->rs_nblocks==0||scan->rs_numblocks==0)
635+
if (block==InvalidBlockNumber)
594636
{
595637
Assert(!BufferIsValid(scan->rs_cbuf));
596638
tuple->t_data=NULL;
597639
return;
598640
}
599641

600-
/*
601-
* Disable reporting to syncscan logic in a backwards scan; it's
602-
* not very likely anyone else is doing the same thing at the same
603-
* time, and much more likely that we'll just bollix things for
604-
* forward scanners.
605-
*/
606-
scan->rs_base.rs_flags &= ~SO_ALLOW_SYNC;
607-
608-
/*
609-
* Start from last page of the scan. Ensure we take into account
610-
* rs_numblocks if it's been adjusted by heap_setscanlimits().
611-
*/
612-
if (scan->rs_numblocks!=InvalidBlockNumber)
613-
block= (scan->rs_startblock+scan->rs_numblocks-1) %scan->rs_nblocks;
614-
elseif (scan->rs_startblock>0)
615-
block=scan->rs_startblock-1;
616-
else
617-
block=scan->rs_nblocks-1;
618642
heapgetpage((TableScanDesc)scan,block);
643+
LockBuffer(scan->rs_cbuf,BUFFER_LOCK_SHARE);
644+
645+
page=BufferGetPage(scan->rs_cbuf);
646+
TestForOldSnapshot(snapshot,scan->rs_base.rs_rd,page);
647+
lines=PageGetMaxOffsetNumber(page);
648+
lineoff=lines;/* final offnum */
649+
scan->rs_inited= true;
619650
}
620651
else
621652
{
622653
/* continue from previously returned page/tuple */
623654
block=scan->rs_cblock;/* current page */
624-
}
655+
LockBuffer(scan->rs_cbuf,BUFFER_LOCK_SHARE);
625656

626-
LockBuffer(scan->rs_cbuf,BUFFER_LOCK_SHARE);
657+
page=BufferGetPage(scan->rs_cbuf);
658+
TestForOldSnapshot(snapshot,scan->rs_base.rs_rd,page);
659+
lines=PageGetMaxOffsetNumber(page);
627660

628-
page=BufferGetPage(scan->rs_cbuf);
629-
TestForOldSnapshot(snapshot,scan->rs_base.rs_rd,page);
630-
lines=PageGetMaxOffsetNumber(page);
631-
632-
if (!scan->rs_inited)
633-
{
634-
lineoff=lines;/* final offnum */
635-
scan->rs_inited= true;
636-
}
637-
else
638-
{
639661
/*
640662
* The previous returned tuple may have been vacuumed since the
641663
* previous scan when we use a non-MVCC snapshot, so we must
@@ -837,38 +859,19 @@ heapgettup_pagemode(HeapScanDesc scan,
837859
{
838860
if (!scan->rs_inited)
839861
{
862+
block=heapgettup_initial_block(scan,dir);
863+
840864
/*
841-
* return null immediately if relation is empty
865+
* Check if we have reached the end of the scan already. This
866+
* could happen if the table is empty or if the parallel workers
867+
* have already finished the scan before we did anything ourselves
842868
*/
843-
if (scan->rs_nblocks==0||scan->rs_numblocks==0)
869+
if (block==InvalidBlockNumber)
844870
{
845871
Assert(!BufferIsValid(scan->rs_cbuf));
846872
tuple->t_data=NULL;
847873
return;
848874
}
849-
if (scan->rs_base.rs_parallel!=NULL)
850-
{
851-
ParallelBlockTableScanDescpbscan=
852-
(ParallelBlockTableScanDesc)scan->rs_base.rs_parallel;
853-
ParallelBlockTableScanWorkerpbscanwork=
854-
scan->rs_parallelworkerdata;
855-
856-
table_block_parallelscan_startblock_init(scan->rs_base.rs_rd,
857-
pbscanwork,pbscan);
858-
859-
block=table_block_parallelscan_nextpage(scan->rs_base.rs_rd,
860-
pbscanwork,pbscan);
861-
862-
/* Other processes might have already finished the scan. */
863-
if (block==InvalidBlockNumber)
864-
{
865-
Assert(!BufferIsValid(scan->rs_cbuf));
866-
tuple->t_data=NULL;
867-
return;
868-
}
869-
}
870-
else
871-
block=scan->rs_startblock;/* first page */
872875
heapgetpage((TableScanDesc)scan,block);
873876
lineindex=0;
874877
scan->rs_inited= true;
@@ -889,58 +892,36 @@ heapgettup_pagemode(HeapScanDesc scan,
889892
}
890893
else
891894
{
892-
/* backward parallel scan not supported */
893-
Assert(scan->rs_base.rs_parallel==NULL);
894-
895895
if (!scan->rs_inited)
896896
{
897+
block=heapgettup_initial_block(scan,dir);
898+
897899
/*
898-
* return null immediately if relation is empty
900+
* Check if we have reached the end of the scan already. This
901+
* could happen if the table is empty.
899902
*/
900-
if (scan->rs_nblocks==0||scan->rs_numblocks==0)
903+
if (block==InvalidBlockNumber)
901904
{
902905
Assert(!BufferIsValid(scan->rs_cbuf));
903906
tuple->t_data=NULL;
904907
return;
905908
}
906909

907-
/*
908-
* Disable reporting to syncscan logic in a backwards scan; it's
909-
* not very likely anyone else is doing the same thing at the same
910-
* time, and much more likely that we'll just bollix things for
911-
* forward scanners.
912-
*/
913-
scan->rs_base.rs_flags &= ~SO_ALLOW_SYNC;
914-
915-
/*
916-
* Start from last page of the scan. Ensure we take into account
917-
* rs_numblocks if it's been adjusted by heap_setscanlimits().
918-
*/
919-
if (scan->rs_numblocks!=InvalidBlockNumber)
920-
block= (scan->rs_startblock+scan->rs_numblocks-1) %scan->rs_nblocks;
921-
elseif (scan->rs_startblock>0)
922-
block=scan->rs_startblock-1;
923-
else
924-
block=scan->rs_nblocks-1;
925910
heapgetpage((TableScanDesc)scan,block);
911+
page=BufferGetPage(scan->rs_cbuf);
912+
TestForOldSnapshot(scan->rs_base.rs_snapshot,scan->rs_base.rs_rd,page);
913+
lines=scan->rs_ntuples;
914+
lineindex=lines-1;
915+
scan->rs_inited= true;
926916
}
927917
else
928918
{
929919
/* continue from previously returned page/tuple */
930920
block=scan->rs_cblock;/* current page */
931-
}
932-
933-
page=BufferGetPage(scan->rs_cbuf);
934-
TestForOldSnapshot(scan->rs_base.rs_snapshot,scan->rs_base.rs_rd,page);
935-
lines=scan->rs_ntuples;
936921

937-
if (!scan->rs_inited)
938-
{
939-
lineindex=lines-1;
940-
scan->rs_inited= true;
941-
}
942-
else
943-
{
922+
page=BufferGetPage(scan->rs_cbuf);
923+
TestForOldSnapshot(scan->rs_base.rs_snapshot,scan->rs_base.rs_rd,page);
924+
lines=scan->rs_ntuples;
944925
lineindex=scan->rs_cindex-1;
945926
}
946927
/* block and lineindex now reference the previous visible tid */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp