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

Commitcfcf56f

Browse files
committed
More refactoring of heapgettup() and heapgettup_pagemode()
Here we further simplify the code in heapgettup() andheapgettup_pagemode() to make better use of the helper functions added inthe previous recent refactors in this area.In passing, remove an unneeded cast added in8ca6d49.Author: Melanie PlagemanReviewed-by: Andres Freund, David RowleyDiscussion:https://postgr.es/m/CAAKRu_YSOnhKsDyFcqJsKtBSrd32DP-jjXmv7hL0BPD-z0TGXQ@mail.gmail.com
1 parent9ba37b2 commitcfcf56f

File tree

1 file changed

+78
-169
lines changed

1 file changed

+78
-169
lines changed

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

Lines changed: 78 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ heapgettup_start_page(HeapScanDesc scan, ScanDirection dir, int *linesleft,
567567

568568
TestForOldSnapshot(scan->rs_base.rs_snapshot,scan->rs_base.rs_rd,page);
569569

570-
*linesleft=PageGetMaxOffsetNumber((Page)page)-FirstOffsetNumber+1;
570+
*linesleft=PageGetMaxOffsetNumber(page)-FirstOffsetNumber+1;
571571

572572
if (ScanDirectionIsForward(dir))
573573
*lineoff=FirstOffsetNumber;
@@ -732,34 +732,17 @@ heapgettup(HeapScanDesc scan,
732732
ScanKeykey)
733733
{
734734
HeapTupletuple=&(scan->rs_ctup);
735-
boolbackward=ScanDirectionIsBackward(dir);
736735
BlockNumberblock;
737736
Pagepage;
738737
OffsetNumberlineoff;
739738
intlinesleft;
740-
ItemIdlpp;
741739

742740
if (unlikely(!scan->rs_inited))
743741
{
744742
block=heapgettup_initial_block(scan,dir);
745-
746-
/*
747-
* Check if we have reached the end of the scan already. This could
748-
* happen if the table is empty or if the parallel workers have
749-
* already finished the scan before we did anything ourselves
750-
*/
751-
if (block==InvalidBlockNumber)
752-
{
753-
Assert(!BufferIsValid(scan->rs_cbuf));
754-
tuple->t_data=NULL;
755-
return;
756-
}
743+
/* ensure rs_cbuf is invalid when we get InvalidBlockNumber */
744+
Assert(block!=InvalidBlockNumber|| !BufferIsValid(scan->rs_cbuf));
757745
scan->rs_inited= true;
758-
759-
heapgetpage((TableScanDesc)scan,block);
760-
761-
LockBuffer(scan->rs_cbuf,BUFFER_LOCK_SHARE);
762-
page=heapgettup_start_page(scan,dir,&linesleft,&lineoff);
763746
}
764747
else
765748
{
@@ -768,69 +751,60 @@ heapgettup(HeapScanDesc scan,
768751

769752
LockBuffer(scan->rs_cbuf,BUFFER_LOCK_SHARE);
770753
page=heapgettup_continue_page(scan,dir,&linesleft,&lineoff);
754+
gotocontinue_page;
771755
}
772756

773757
/*
774758
* advance the scan until we find a qualifying tuple or run out of stuff
775759
* to scan
776760
*/
777-
lpp=PageGetItemId(page,lineoff);
778-
for (;;)
761+
while (block!=InvalidBlockNumber)
779762
{
763+
heapgetpage((TableScanDesc)scan,block);
764+
LockBuffer(scan->rs_cbuf,BUFFER_LOCK_SHARE);
765+
page=heapgettup_start_page(scan,dir,&linesleft,&lineoff);
766+
continue_page:
767+
780768
/*
781769
* Only continue scanning the page while we have lines left.
782770
*
783771
* Note that this protects us from accessing line pointers past
784772
* PageGetMaxOffsetNumber(); both for forward scans when we resume the
785773
* table scan, and for when we start scanning a new page.
786774
*/
787-
while (linesleft>0)
775+
for (;linesleft>0;linesleft--,lineoff+=dir)
788776
{
789-
if (ItemIdIsNormal(lpp))
790-
{
791-
boolvalid;
777+
boolvisible;
778+
ItemIdlpp=PageGetItemId(page,lineoff);
792779

793-
tuple->t_data= (HeapTupleHeader)PageGetItem(page,lpp);
794-
tuple->t_len=ItemIdGetLength(lpp);
795-
ItemPointerSet(&(tuple->t_self),block,lineoff);
780+
if (!ItemIdIsNormal(lpp))
781+
continue;
796782

797-
/*
798-
* if current tuple qualifies, return it.
799-
*/
800-
valid=HeapTupleSatisfiesVisibility(tuple,
801-
scan->rs_base.rs_snapshot,
802-
scan->rs_cbuf);
783+
tuple->t_data= (HeapTupleHeader)PageGetItem(page,lpp);
784+
tuple->t_len=ItemIdGetLength(lpp);
785+
ItemPointerSet(&(tuple->t_self),block,lineoff);
803786

804-
HeapCheckForSerializableConflictOut(valid,scan->rs_base.rs_rd,
805-
tuple,scan->rs_cbuf,
806-
scan->rs_base.rs_snapshot);
787+
visible=HeapTupleSatisfiesVisibility(tuple,
788+
scan->rs_base.rs_snapshot,
789+
scan->rs_cbuf);
807790

808-
if (valid&&key!=NULL)
809-
valid=HeapKeyTest(tuple,RelationGetDescr(scan->rs_base.rs_rd),
810-
nkeys,key);
791+
HeapCheckForSerializableConflictOut(visible,scan->rs_base.rs_rd,
792+
tuple,scan->rs_cbuf,
793+
scan->rs_base.rs_snapshot);
811794

812-
if (valid)
813-
{
814-
LockBuffer(scan->rs_cbuf,BUFFER_LOCK_UNLOCK);
815-
scan->rs_coffset=lineoff;
816-
return;
817-
}
818-
}
795+
/* skip tuples not visible to this snapshot */
796+
if (!visible)
797+
continue;
819798

820-
/*
821-
* otherwise move to the next item on the page
822-
*/
823-
--linesleft;
824-
if (backward)
825-
{
826-
--lpp;/* move back in this page's ItemId array */
827-
--lineoff;
828-
}
829-
else
830-
{
831-
++lpp;/* move forward in this page's ItemId array */
832-
++lineoff;
833-
}
799+
/* skip any tuples that don't match the scan key */
800+
if (key!=NULL&&
801+
!HeapKeyTest(tuple,RelationGetDescr(scan->rs_base.rs_rd),
802+
nkeys,key))
803+
continue;
804+
805+
LockBuffer(scan->rs_cbuf,BUFFER_LOCK_UNLOCK);
806+
scan->rs_coffset=lineoff;
807+
return;
834808
}
835809

836810
/*
@@ -841,40 +815,16 @@ heapgettup(HeapScanDesc scan,
841815

842816
/* get the BlockNumber to scan next */
843817
block=heapgettup_advance_block(scan,block,dir);
818+
}
844819

845-
/*
846-
* return NULL if we've exhausted all the pages
847-
*/
848-
if (block==InvalidBlockNumber)
849-
{
850-
if (BufferIsValid(scan->rs_cbuf))
851-
ReleaseBuffer(scan->rs_cbuf);
852-
scan->rs_cbuf=InvalidBuffer;
853-
scan->rs_cblock=InvalidBlockNumber;
854-
tuple->t_data=NULL;
855-
scan->rs_inited= false;
856-
return;
857-
}
858-
859-
heapgetpage((TableScanDesc)scan,block);
860-
861-
LockBuffer(scan->rs_cbuf,BUFFER_LOCK_SHARE);
820+
/* end of scan */
821+
if (BufferIsValid(scan->rs_cbuf))
822+
ReleaseBuffer(scan->rs_cbuf);
862823

863-
page=BufferGetPage(scan->rs_cbuf);
864-
TestForOldSnapshot(scan->rs_base.rs_snapshot,scan->rs_base.rs_rd,
865-
page);
866-
linesleft=PageGetMaxOffsetNumber(page);
867-
if (backward)
868-
{
869-
lineoff=linesleft;
870-
lpp=PageGetItemId(page,linesleft);
871-
}
872-
else
873-
{
874-
lineoff=FirstOffsetNumber;
875-
lpp=PageGetItemId(page,FirstOffsetNumber);
876-
}
877-
}
824+
scan->rs_cbuf=InvalidBuffer;
825+
scan->rs_cblock=InvalidBlockNumber;
826+
tuple->t_data=NULL;
827+
scan->rs_inited= false;
878828
}
879829

880830
/* ----------------
@@ -897,35 +847,16 @@ heapgettup_pagemode(HeapScanDesc scan,
897847
ScanKeykey)
898848
{
899849
HeapTupletuple=&(scan->rs_ctup);
900-
boolbackward=ScanDirectionIsBackward(dir);
901850
BlockNumberblock;
902851
Pagepage;
903852
intlineindex;
904-
OffsetNumberlineoff;
905853
intlinesleft;
906-
ItemIdlpp;
907854

908855
if (unlikely(!scan->rs_inited))
909856
{
910857
block=heapgettup_initial_block(scan,dir);
911-
912-
/*
913-
* Check if we have reached the end of the scan already. This could
914-
* happen if the table is empty or if the other workers in a parallel
915-
* scan have already finished the scan.
916-
*/
917-
if (block==InvalidBlockNumber)
918-
{
919-
Assert(!BufferIsValid(scan->rs_cbuf));
920-
tuple->t_data=NULL;
921-
return;
922-
}
923-
924-
heapgetpage((TableScanDesc)scan,block);
925-
page=BufferGetPage(scan->rs_cbuf);
926-
TestForOldSnapshot(scan->rs_base.rs_snapshot,scan->rs_base.rs_rd,page);
927-
linesleft=scan->rs_ntuples;
928-
lineindex=ScanDirectionIsForward(dir) ?0 :linesleft-1;
858+
/* ensure rs_cbuf is invalid when we get InvalidBlockNumber */
859+
Assert(block!=InvalidBlockNumber|| !BufferIsValid(scan->rs_cbuf));
929860
scan->rs_inited= true;
930861
}
931862
else
@@ -940,16 +871,31 @@ heapgettup_pagemode(HeapScanDesc scan,
940871
linesleft=scan->rs_ntuples-lineindex;
941872
else
942873
linesleft=scan->rs_cindex;
874+
/* lineindex now references the next or previous visible tid */
875+
876+
gotocontinue_page;
943877
}
944878

945879
/*
946880
* advance the scan until we find a qualifying tuple or run out of stuff
947881
* to scan
948882
*/
949-
for (;;)
883+
while (block!=InvalidBlockNumber)
950884
{
951-
while (linesleft>0)
885+
heapgetpage((TableScanDesc)scan,block);
886+
page=BufferGetPage(scan->rs_cbuf);
887+
TestForOldSnapshot(scan->rs_base.rs_snapshot,scan->rs_base.rs_rd,page);
888+
linesleft=scan->rs_ntuples;
889+
lineindex=ScanDirectionIsForward(dir) ?0 :linesleft-1;
890+
891+
/* lineindex now references the next or previous visible tid */
892+
continue_page:
893+
894+
for (;linesleft>0;linesleft--,lineindex+=dir)
952895
{
896+
ItemIdlpp;
897+
OffsetNumberlineoff;
898+
953899
lineoff=scan->rs_vistuples[lineindex];
954900
lpp=PageGetItemId(page,lineoff);
955901
Assert(ItemIdIsNormal(lpp));
@@ -958,64 +904,27 @@ heapgettup_pagemode(HeapScanDesc scan,
958904
tuple->t_len=ItemIdGetLength(lpp);
959905
ItemPointerSet(&(tuple->t_self),block,lineoff);
960906

961-
/*
962-
* if current tuple qualifies, return it.
963-
*/
964-
if (key!=NULL)
965-
{
966-
boolvalid;
967-
968-
valid=HeapKeyTest(tuple,RelationGetDescr(scan->rs_base.rs_rd),
969-
nkeys,key);
970-
if (valid)
971-
{
972-
scan->rs_cindex=lineindex;
973-
return;
974-
}
975-
}
976-
else
977-
{
978-
scan->rs_cindex=lineindex;
979-
return;
980-
}
907+
/* skip any tuples that don't match the scan key */
908+
if (key!=NULL&&
909+
!HeapKeyTest(tuple,RelationGetDescr(scan->rs_base.rs_rd),
910+
nkeys,key))
911+
continue;
981912

982-
/*
983-
* otherwise move to the next item on the page
984-
*/
985-
--linesleft;
986-
if (backward)
987-
--lineindex;
988-
else
989-
++lineindex;
913+
scan->rs_cindex=lineindex;
914+
return;
990915
}
991916

992917
/* get the BlockNumber to scan next */
993918
block=heapgettup_advance_block(scan,block,dir);
994-
995-
/*
996-
* return NULL if we've exhausted all the pages
997-
*/
998-
if (block==InvalidBlockNumber)
999-
{
1000-
if (BufferIsValid(scan->rs_cbuf))
1001-
ReleaseBuffer(scan->rs_cbuf);
1002-
scan->rs_cbuf=InvalidBuffer;
1003-
scan->rs_cblock=InvalidBlockNumber;
1004-
tuple->t_data=NULL;
1005-
scan->rs_inited= false;
1006-
return;
1007-
}
1008-
1009-
heapgetpage((TableScanDesc)scan,block);
1010-
1011-
page=BufferGetPage(scan->rs_cbuf);
1012-
TestForOldSnapshot(scan->rs_base.rs_snapshot,scan->rs_base.rs_rd,page);
1013-
linesleft=scan->rs_ntuples;
1014-
if (backward)
1015-
lineindex=linesleft-1;
1016-
else
1017-
lineindex=0;
1018919
}
920+
921+
/* end of scan */
922+
if (BufferIsValid(scan->rs_cbuf))
923+
ReleaseBuffer(scan->rs_cbuf);
924+
scan->rs_cbuf=InvalidBuffer;
925+
scan->rs_cblock=InvalidBlockNumber;
926+
tuple->t_data=NULL;
927+
scan->rs_inited= false;
1019928
}
1020929

1021930

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp