@@ -576,101 +576,67 @@ heapgettup(HeapScanDesc scan,
576
576
BlockNumber block ;
577
577
bool finished ;
578
578
Page page ;
579
- int lines ;
580
579
OffsetNumber lineoff ;
581
580
int linesleft ;
582
581
ItemId lpp ;
583
582
584
- /*
585
- * calculate next starting lineoff, given scan direction
586
- */
587
- if (ScanDirectionIsForward (dir ))
583
+ if (unlikely (!scan -> rs_inited ))
588
584
{
589
- if (!scan -> rs_inited )
590
- {
591
- block = heapgettup_initial_block (scan , dir );
585
+ block = heapgettup_initial_block (scan , dir );
592
586
593
- /*
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
597
- */
598
- if (block == InvalidBlockNumber )
599
- {
600
- Assert (!BufferIsValid (scan -> rs_cbuf ));
601
- tuple -> t_data = NULL ;
602
- return ;
603
- }
604
- heapgetpage ((TableScanDesc ) scan , block );
605
- lineoff = FirstOffsetNumber ; /* first offnum */
606
- scan -> rs_inited = true;
607
- }
608
- else
587
+ /*
588
+ * Check if we have reached the end of the scan already. This could
589
+ * happen if the table is empty or if the parallel workers have
590
+ * already finished the scan before we did anything ourselves
591
+ */
592
+ if (block == InvalidBlockNumber )
609
593
{
610
- /* continue from previously returned page/tuple */
611
- block = scan -> rs_cblock ; /* current page */
612
- lineoff = /* next offnum */
613
- OffsetNumberNext (ItemPointerGetOffsetNumber (& (tuple -> t_self )));
594
+ Assert (!BufferIsValid (scan -> rs_cbuf ));
595
+ tuple -> t_data = NULL ;
596
+ return ;
614
597
}
615
598
616
- LockBuffer ( scan -> rs_cbuf , BUFFER_LOCK_SHARE );
599
+ heapgetpage (( TableScanDesc ) scan , block );
617
600
601
+ LockBuffer (scan -> rs_cbuf , BUFFER_LOCK_SHARE );
618
602
page = BufferGetPage (scan -> rs_cbuf );
619
603
TestForOldSnapshot (snapshot , scan -> rs_base .rs_rd , page );
620
- lines = PageGetMaxOffsetNumber (page );
621
- /* block and lineoff now reference the physically next tid */
622
604
623
- linesleft = lines - lineoff + 1 ;
605
+ linesleft = PageGetMaxOffsetNumber (page ) - FirstOffsetNumber + 1 ;
606
+
607
+ if (ScanDirectionIsForward (dir ))
608
+ lineoff = FirstOffsetNumber ; /* first offnum */
609
+ else
610
+ lineoff = (OffsetNumber ) linesleft ;
611
+
612
+ scan -> rs_inited = true;
624
613
}
625
614
else
626
615
{
627
- if (!scan -> rs_inited )
628
- {
629
- block = heapgettup_initial_block (scan , dir );
630
-
631
- /*
632
- * Check if we have reached the end of the scan already. This
633
- * could happen if the table is empty.
634
- */
635
- if (block == InvalidBlockNumber )
636
- {
637
- Assert (!BufferIsValid (scan -> rs_cbuf ));
638
- tuple -> t_data = NULL ;
639
- return ;
640
- }
616
+ /* continue from previously returned page/tuple */
617
+ block = scan -> rs_cblock ;
641
618
642
- heapgetpage ((TableScanDesc ) scan , block );
643
- LockBuffer (scan -> rs_cbuf , BUFFER_LOCK_SHARE );
619
+ LockBuffer (scan -> rs_cbuf , BUFFER_LOCK_SHARE );
620
+ page = BufferGetPage (scan -> rs_cbuf );
621
+ TestForOldSnapshot (snapshot , scan -> rs_base .rs_rd , page );
644
622
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;
623
+ if (ScanDirectionIsForward (dir ))
624
+ {
625
+ lineoff = OffsetNumberNext (scan -> rs_coffset );
626
+ linesleft = PageGetMaxOffsetNumber (page ) - lineoff + 1 ;
650
627
}
651
628
else
652
629
{
653
- /* continue from previously returned page/tuple */
654
- block = scan -> rs_cblock ; /* current page */
655
- LockBuffer (scan -> rs_cbuf , BUFFER_LOCK_SHARE );
656
-
657
- page = BufferGetPage (scan -> rs_cbuf );
658
- TestForOldSnapshot (snapshot , scan -> rs_base .rs_rd , page );
659
- lines = PageGetMaxOffsetNumber (page );
660
-
661
630
/*
662
631
* The previous returned tuple may have been vacuumed since the
663
632
* previous scan when we use a non-MVCC snapshot, so we must
664
633
* re-establish the lineoff <= PageGetMaxOffsetNumber(page)
665
634
* invariant
666
635
*/
667
- lineoff = /* previous offnum */
668
- Min ( lines ,
669
- OffsetNumberPrev ( ItemPointerGetOffsetNumber ( & ( tuple -> t_self )))) ;
636
+ lineoff = Min ( PageGetMaxOffsetNumber ( page ),
637
+ OffsetNumberPrev ( scan -> rs_coffset ));
638
+ linesleft = lineoff ;
670
639
}
671
- /* block and lineoff now reference the physically previous tid */
672
-
673
- linesleft = lineoff ;
674
640
}
675
641
676
642
/*
@@ -715,6 +681,7 @@ heapgettup(HeapScanDesc scan,
715
681
if (valid )
716
682
{
717
683
LockBuffer (scan -> rs_cbuf , BUFFER_LOCK_UNLOCK );
684
+ scan -> rs_coffset = lineoff ;
718
685
return ;
719
686
}
720
687
}
@@ -807,12 +774,11 @@ heapgettup(HeapScanDesc scan,
807
774
808
775
page = BufferGetPage (scan -> rs_cbuf );
809
776
TestForOldSnapshot (snapshot , scan -> rs_base .rs_rd , page );
810
- lines = PageGetMaxOffsetNumber (page );
811
- linesleft = lines ;
777
+ linesleft = PageGetMaxOffsetNumber (page );
812
778
if (backward )
813
779
{
814
- lineoff = lines ;
815
- lpp = PageGetItemId (page , lines );
780
+ lineoff = linesleft ;
781
+ lpp = PageGetItemId (page , linesleft );
816
782
}
817
783
else
818
784
{
@@ -846,87 +812,46 @@ heapgettup_pagemode(HeapScanDesc scan,
846
812
BlockNumber block ;
847
813
bool finished ;
848
814
Page page ;
849
- int lines ;
850
815
int lineindex ;
851
816
OffsetNumber lineoff ;
852
817
int linesleft ;
853
818
ItemId lpp ;
854
819
855
- /*
856
- * calculate next starting lineindex, given scan direction
857
- */
858
- if (ScanDirectionIsForward (dir ))
820
+ if (unlikely (!scan -> rs_inited ))
859
821
{
860
- if (!scan -> rs_inited )
861
- {
862
- block = heapgettup_initial_block (scan , dir );
822
+ block = heapgettup_initial_block (scan , dir );
863
823
864
- /*
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
868
- */
869
- if (block == InvalidBlockNumber )
870
- {
871
- Assert (!BufferIsValid (scan -> rs_cbuf ));
872
- tuple -> t_data = NULL ;
873
- return ;
874
- }
875
- heapgetpage ((TableScanDesc ) scan , block );
876
- lineindex = 0 ;
877
- scan -> rs_inited = true;
878
- }
879
- else
824
+ /*
825
+ * Check if we have reached the end of the scan already. This could
826
+ * happen if the table is empty or if the other workers in a parallel
827
+ * scan have already finished the scan.
828
+ */
829
+ if (block == InvalidBlockNumber )
880
830
{
881
- /* continue from previously returned page/tuple */
882
- block = scan -> rs_cblock ; /* current page */
883
- lineindex = scan -> rs_cindex + 1 ;
831
+ Assert (! BufferIsValid ( scan -> rs_cbuf ));
832
+ tuple -> t_data = NULL ;
833
+ return ;
884
834
}
885
835
836
+ heapgetpage ((TableScanDesc ) scan , block );
886
837
page = BufferGetPage (scan -> rs_cbuf );
887
838
TestForOldSnapshot (scan -> rs_base .rs_snapshot , scan -> rs_base .rs_rd , page );
888
- lines = scan -> rs_ntuples ;
889
- /* block and lineindex now reference the next visible tid */
890
-
891
- linesleft = lines - lineindex ;
839
+ linesleft = scan -> rs_ntuples ;
840
+ lineindex = ScanDirectionIsForward (dir ) ? 0 : linesleft - 1 ;
841
+ scan -> rs_inited = true;
892
842
}
893
843
else
894
844
{
895
- if (!scan -> rs_inited )
896
- {
897
- block = heapgettup_initial_block (scan , dir );
898
-
899
- /*
900
- * Check if we have reached the end of the scan already. This
901
- * could happen if the table is empty.
902
- */
903
- if (block == InvalidBlockNumber )
904
- {
905
- Assert (!BufferIsValid (scan -> rs_cbuf ));
906
- tuple -> t_data = NULL ;
907
- return ;
908
- }
845
+ /* continue from previously returned page/tuple */
846
+ block = scan -> rs_cblock ; /* current page */
847
+ page = BufferGetPage (scan -> rs_cbuf );
848
+ TestForOldSnapshot (scan -> rs_base .rs_snapshot , scan -> rs_base .rs_rd , page );
909
849
910
- 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;
916
- }
850
+ lineindex = scan -> rs_cindex + dir ;
851
+ if (ScanDirectionIsForward (dir ))
852
+ linesleft = scan -> rs_ntuples - lineindex ;
917
853
else
918
- {
919
- /* continue from previously returned page/tuple */
920
- block = scan -> rs_cblock ; /* current page */
921
-
922
- page = BufferGetPage (scan -> rs_cbuf );
923
- TestForOldSnapshot (scan -> rs_base .rs_snapshot , scan -> rs_base .rs_rd , page );
924
- lines = scan -> rs_ntuples ;
925
- lineindex = scan -> rs_cindex - 1 ;
926
- }
927
- /* block and lineindex now reference the previous visible tid */
928
-
929
- linesleft = lineindex + 1 ;
854
+ linesleft = scan -> rs_cindex ;
930
855
}
931
856
932
857
/*
@@ -1041,10 +966,9 @@ heapgettup_pagemode(HeapScanDesc scan,
1041
966
1042
967
page = BufferGetPage (scan -> rs_cbuf );
1043
968
TestForOldSnapshot (scan -> rs_base .rs_snapshot , scan -> rs_base .rs_rd , page );
1044
- lines = scan -> rs_ntuples ;
1045
- linesleft = lines ;
969
+ linesleft = scan -> rs_ntuples ;
1046
970
if (backward )
1047
- lineindex = lines - 1 ;
971
+ lineindex = linesleft - 1 ;
1048
972
else
1049
973
lineindex = 0 ;
1050
974
}
0 commit comments