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

Commitf9bc34f

Browse files
committed
Further refactor of heapgettup and heapgettup_pagemode
Backward and forward scans share much of the same page acquisition code.Here we consolidate that code to reduce some duplication.Additionally, add a new rs_coffset field to HeapScanDescData to track theoffset of the current tuple. The new field fits nicely into the paddingbetween a bool and BlockNumber field and saves having to look at the lastreturned tuple to figure out which offset we should be looking at for thecurrent tuple.Author: Melanie PlagemanReviewed-by: David RowleyDiscussion:https://postgr.es/m/CAAKRu_bvkhka0CZQun28KTqhuUh5ZqY=_T8QEqZqOL02rpi2bw@mail.gmail.com
1 parentcdf6518 commitf9bc34f

File tree

2 files changed

+63
-138
lines changed

2 files changed

+63
-138
lines changed

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

Lines changed: 62 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -576,101 +576,67 @@ heapgettup(HeapScanDesc scan,
576576
BlockNumberblock;
577577
boolfinished;
578578
Pagepage;
579-
intlines;
580579
OffsetNumberlineoff;
581580
intlinesleft;
582581
ItemIdlpp;
583582

584-
/*
585-
* calculate next starting lineoff, given scan direction
586-
*/
587-
if (ScanDirectionIsForward(dir))
583+
if (unlikely(!scan->rs_inited))
588584
{
589-
if (!scan->rs_inited)
590-
{
591-
block=heapgettup_initial_block(scan,dir);
585+
block=heapgettup_initial_block(scan,dir);
592586

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)
609593
{
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;
614597
}
615598

616-
LockBuffer(scan->rs_cbuf,BUFFER_LOCK_SHARE);
599+
heapgetpage((TableScanDesc)scan,block);
617600

601+
LockBuffer(scan->rs_cbuf,BUFFER_LOCK_SHARE);
618602
page=BufferGetPage(scan->rs_cbuf);
619603
TestForOldSnapshot(snapshot,scan->rs_base.rs_rd,page);
620-
lines=PageGetMaxOffsetNumber(page);
621-
/* block and lineoff now reference the physically next tid */
622604

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;
624613
}
625614
else
626615
{
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;
641618

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);
644622

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;
650627
}
651628
else
652629
{
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-
661630
/*
662631
* The previous returned tuple may have been vacuumed since the
663632
* previous scan when we use a non-MVCC snapshot, so we must
664633
* re-establish the lineoff <= PageGetMaxOffsetNumber(page)
665634
* invariant
666635
*/
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;
670639
}
671-
/* block and lineoff now reference the physically previous tid */
672-
673-
linesleft=lineoff;
674640
}
675641

676642
/*
@@ -715,6 +681,7 @@ heapgettup(HeapScanDesc scan,
715681
if (valid)
716682
{
717683
LockBuffer(scan->rs_cbuf,BUFFER_LOCK_UNLOCK);
684+
scan->rs_coffset=lineoff;
718685
return;
719686
}
720687
}
@@ -807,12 +774,11 @@ heapgettup(HeapScanDesc scan,
807774

808775
page=BufferGetPage(scan->rs_cbuf);
809776
TestForOldSnapshot(snapshot,scan->rs_base.rs_rd,page);
810-
lines=PageGetMaxOffsetNumber(page);
811-
linesleft=lines;
777+
linesleft=PageGetMaxOffsetNumber(page);
812778
if (backward)
813779
{
814-
lineoff=lines;
815-
lpp=PageGetItemId(page,lines);
780+
lineoff=linesleft;
781+
lpp=PageGetItemId(page,linesleft);
816782
}
817783
else
818784
{
@@ -846,87 +812,46 @@ heapgettup_pagemode(HeapScanDesc scan,
846812
BlockNumberblock;
847813
boolfinished;
848814
Pagepage;
849-
intlines;
850815
intlineindex;
851816
OffsetNumberlineoff;
852817
intlinesleft;
853818
ItemIdlpp;
854819

855-
/*
856-
* calculate next starting lineindex, given scan direction
857-
*/
858-
if (ScanDirectionIsForward(dir))
820+
if (unlikely(!scan->rs_inited))
859821
{
860-
if (!scan->rs_inited)
861-
{
862-
block=heapgettup_initial_block(scan,dir);
822+
block=heapgettup_initial_block(scan,dir);
863823

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)
880830
{
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;
884834
}
885835

836+
heapgetpage((TableScanDesc)scan,block);
886837
page=BufferGetPage(scan->rs_cbuf);
887838
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;
892842
}
893843
else
894844
{
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);
909849

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;
917853
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;
930855
}
931856

932857
/*
@@ -1041,10 +966,9 @@ heapgettup_pagemode(HeapScanDesc scan,
1041966

1042967
page=BufferGetPage(scan->rs_cbuf);
1043968
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;
1046970
if (backward)
1047-
lineindex=lines-1;
971+
lineindex=linesleft-1;
1048972
else
1049973
lineindex=0;
1050974
}

‎src/include/access/heapam.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ typedef struct HeapScanDescData
5757

5858
/* scan current state */
5959
boolrs_inited;/* false = scan not init'd yet */
60+
OffsetNumberrs_coffset;/* current offset # in non-page-at-a-time mode */
6061
BlockNumberrs_cblock;/* current block # in scan, if any */
6162
Bufferrs_cbuf;/* current buffer in scan, if any */
6263
/* NB: if rs_cbuf is not InvalidBuffer, we hold a pin on that buffer */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp