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

Appearance settings

Commit cfcf56f

Browse filesBrowse files
committed
More refactoring of heapgettup() and heapgettup_pagemode()
Here we further simplify the code in heapgettup() and heapgettup_pagemode() to make better use of the helper functions added in the previous recent refactors in this area. In passing, remove an unneeded cast added in 8ca6d49. Author: Melanie Plageman Reviewed-by: Andres Freund, David Rowley Discussion: https://postgr.es/m/CAAKRu_YSOnhKsDyFcqJsKtBSrd32DP-jjXmv7hL0BPD-z0TGXQ@mail.gmail.com
1 parent 9ba37b2 commit cfcf56f
Copy full SHA for cfcf56f

File tree

1 file changed

+78
-169
lines changed
Filter options

1 file changed

+78
-169
lines changed

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

Copy file name to clipboardExpand all lines: src/backend/access/heap/heapam.c
+78-169Lines 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
ScanKey key)
733733
{
734734
HeapTuple tuple = &(scan->rs_ctup);
735-
bool backward = ScanDirectionIsBackward(dir);
736735
BlockNumber block;
737736
Page page;
738737
OffsetNumber lineoff;
739738
int linesleft;
740-
ItemId lpp;
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+
goto continue_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-
bool valid;
777+
bool visible;
778+
ItemId lpp = 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
ScanKey key)
898848
{
899849
HeapTuple tuple = &(scan->rs_ctup);
900-
bool backward = ScanDirectionIsBackward(dir);
901850
BlockNumber block;
902851
Page page;
903852
int lineindex;
904-
OffsetNumber lineoff;
905853
int linesleft;
906-
ItemId lpp;
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+
goto continue_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+
ItemId lpp;
897+
OffsetNumber lineoff;
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-
bool valid;
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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.