@@ -135,51 +135,6 @@ callConsistentFn(RumState * rumstate, RumScanKey key)
135
135
return res ;
136
136
}
137
137
138
- /*
139
- * Tries to refind previously taken ItemPointer on a posting page.
140
- */
141
- static bool
142
- findItemInPostingPage (Page page , RumKey * item , int16 * off ,
143
- OffsetNumber attno , OffsetNumber attnum ,
144
- ScanDirection scanDirection , RumState * rumstate )
145
- {
146
- OffsetNumber maxoff = RumPageGetOpaque (page )-> maxoff ;
147
- int res ;
148
- Pointer ptr ;
149
- RumKey iter_item ;
150
-
151
- ItemPointerSetMin (& iter_item .iptr );
152
-
153
- if (RumPageGetOpaque (page )-> flags & RUM_DELETED )
154
- /* page was deleted by concurrent vacuum */
155
- return false;
156
-
157
- ptr = RumDataPageGetData (page );
158
-
159
- /*
160
- * scan page to find equal or first greater value
161
- */
162
- for (* off = FirstOffsetNumber ; * off <= maxoff ; (* off )++ )
163
- {
164
- ptr = rumDataPageLeafRead (ptr , attnum , & iter_item , rumstate );
165
- res = compareRumKey (rumstate , attno , item , & iter_item );
166
-
167
- if (res == 0 )
168
- {
169
- return true;
170
- }
171
- else if (res < 0 )
172
- {
173
- if (ScanDirectionIsBackward (scanDirection ) &&
174
- * off > FirstOffsetNumber )
175
- (* off )-- ;
176
- return true;
177
- }
178
- }
179
-
180
- return false;
181
- }
182
-
183
138
/*
184
139
* Goes to the next page if current offset is outside of bounds
185
140
*/
@@ -650,6 +605,8 @@ startScanEntry(RumState * rumstate, RumScanEntry entry)
650
605
651
606
LockBuffer (entry -> buffer , RUM_UNLOCK );
652
607
entry -> isFinished = setListPositionScanEntry (rumstate , entry );
608
+ if (!entry -> isFinished )
609
+ entry -> curRumKey = entry -> list [entry -> offset ];
653
610
}
654
611
else if (RumGetNPosting (itup ) > 0 )
655
612
{
@@ -659,6 +616,8 @@ startScanEntry(RumState * rumstate, RumScanEntry entry)
659
616
660
617
rumReadTuple (rumstate , entry -> attnum , itup , entry -> list );
661
618
entry -> isFinished = setListPositionScanEntry (rumstate , entry );
619
+ if (!entry -> isFinished )
620
+ entry -> curRumKey = entry -> list [entry -> offset ];
662
621
}
663
622
664
623
if (entry -> queryCategory == RUM_CAT_EMPTY_QUERY &&
@@ -837,26 +796,12 @@ entryGetNextItem(RumState * rumstate, RumScanEntry entry)
837
796
838
797
for (;;)
839
798
{
840
- if (ScanDirectionIsForward (entry -> scanDirection ))
841
- {
842
- if (entry -> offset < entry -> nlist )
843
- {
844
- entry -> curRumKey = entry -> list [entry -> offset ];
845
- entry -> offset ++ ;
846
- return ;
847
- }
848
- }
849
- else if (ScanDirectionIsBackward (entry -> scanDirection ))
799
+ if (entry -> offset >= 0 && entry -> offset < entry -> nlist )
850
800
{
851
- if (entry -> offset >= 0 )
852
- {
853
- entry -> curRumKey = entry -> list [entry -> offset ];
854
- entry -> offset -- ;
855
- return ;
856
- }
801
+ entry -> curRumKey = entry -> list [entry -> offset ];
802
+ entry -> offset += entry -> scanDirection ;
803
+ return ;
857
804
}
858
- else
859
- elog (ERROR ,"NoMovementScanDirection" );
860
805
861
806
LockBuffer (entry -> buffer , RUM_SHARE );
862
807
page = BufferGetPage (entry -> buffer );
@@ -871,6 +816,13 @@ entryGetNextItem(RumState * rumstate, RumScanEntry entry)
871
816
872
817
for (;;)
873
818
{
819
+ OffsetNumber maxoff ,
820
+ i ;
821
+ Pointer ptr ;
822
+ RumKey item ;
823
+ bool searchBorder =
824
+ (ScanDirectionIsForward (entry -> scanDirection ) &&
825
+ ItemPointerIsValid (& entry -> curRumKey .iptr ));
874
826
/*
875
827
* It's needed to go by right link. During that we should refind
876
828
* first ItemPointer greater that stored
@@ -896,55 +848,48 @@ entryGetNextItem(RumState * rumstate, RumScanEntry entry)
896
848
entry -> gdi -> stack -> blkno = BufferGetBlockNumber (entry -> buffer );
897
849
page = BufferGetPage (entry -> buffer );
898
850
899
- entry -> offset = InvalidOffsetNumber ;
900
- if (!ItemPointerIsValid (& entry -> curRumKey .iptr ) ||
901
- findItemInPostingPage (page , & entry -> curRumKey , & entry -> offset ,
902
- entry -> attnumOrig , entry -> attnum ,
903
- entry -> scanDirection , rumstate ))
904
- {
905
- OffsetNumber maxoff ,
906
- i ;
907
- Pointer ptr ;
908
- RumKey item ;
909
-
910
- ItemPointerSetMin (& item .iptr );
911
-
912
- /*
913
- * Found position equal to or greater than stored
914
- */
915
- maxoff = RumPageGetOpaque (page )-> maxoff ;
916
- entry -> nlist = maxoff ;
851
+ entry -> offset = -1 ;
852
+ maxoff = RumPageGetOpaque (page )-> maxoff ;
853
+ entry -> nlist = maxoff ;
854
+ ItemPointerSetMin (& item .iptr );
855
+ ptr = RumDataPageGetData (page );
917
856
918
- ptr = RumDataPageGetData (page );
857
+ for (i = FirstOffsetNumber ; i <= maxoff ; i = OffsetNumberNext (i ))
858
+ {
859
+ ptr = rumDataPageLeafRead (ptr , entry -> attnum , & item , rumstate );
860
+ entry -> list [i - FirstOffsetNumber ] = item ;
919
861
920
- for ( i = FirstOffsetNumber ; i <= maxoff ; i = OffsetNumberNext ( i ) )
862
+ if ( searchBorder )
921
863
{
922
- ptr = rumDataPageLeafRead (ptr , entry -> attnum , & item ,
923
- rumstate );
924
- entry -> list [i - FirstOffsetNumber ] = item ;
864
+ /* don't search position for backward scan,
865
+ because of split algorithm */
866
+ int cmp = compareRumKey (rumstate ,
867
+ entry -> attnumOrig ,
868
+ & entry -> curRumKey ,
869
+ & item );
870
+
871
+ if (cmp > 0 )
872
+ {
873
+ entry -> offset = i - FirstOffsetNumber ;
874
+ searchBorder = false;
875
+ }
925
876
}
877
+ }
926
878
927
- LockBuffer (entry -> buffer , RUM_UNLOCK );
879
+ LockBuffer (entry -> buffer , RUM_UNLOCK );
928
880
929
- if (!ItemPointerIsValid (& entry -> curRumKey .iptr ) ||
930
- compareRumKey (rumstate , entry -> attnumOrig ,
931
- & entry -> curRumKey ,
932
- & entry -> list [entry -> offset - 1 ]) == 0 )
933
- {
934
- /*
935
- * First pages are deleted or empty, or we found exact
936
- * position, so break inner loop and continue outer one.
937
- */
881
+ if (entry -> offset < 0 )
882
+ {
883
+ if (ScanDirectionIsForward (entry -> scanDirection ) &&
884
+ ItemPointerIsValid (& entry -> curRumKey .iptr ))
885
+ /* go on next page */
938
886
break ;
939
- }
940
-
941
- /*
942
- * Find greater than entry->curItem position, store it.
943
- */
944
- entry -> curRumKey = entry -> list [entry -> offset - 1 ];
945
-
946
- return ;
887
+ entry -> offset = (ScanDirectionIsForward (entry -> scanDirection )) ?
888
+ 0 : entry -> nlist - 1 ;
947
889
}
890
+
891
+ entry -> curRumKey = entry -> list [entry -> offset ];
892
+ return ;
948
893
}
949
894
}
950
895
}
@@ -1635,7 +1580,7 @@ scanPage(RumState * rumstate, RumScanEntry entry, RumKey *item, Page page,
1635
1580
1636
1581
ItemPointerSetMin (& iter_item .iptr );
1637
1582
1638
- if (!RumPageRightMost (page ))
1583
+ if (ScanDirectionIsForward ( entry -> scanDirection ) && !RumPageRightMost (page ))
1639
1584
{
1640
1585
cmp = compareRumKey (rumstate , entry -> attnumOrig ,
1641
1586
RumDataPageGetRightBound (page ), item );
@@ -1683,7 +1628,7 @@ scanPage(RumState * rumstate, RumScanEntry entry, RumKey *item, Page page,
1683
1628
}
1684
1629
}
1685
1630
1686
- if (ScanDirectionIsBackward (entry -> scanDirection ))
1631
+ if (ScanDirectionIsBackward (entry -> scanDirection ) && first >= maxoff )
1687
1632
{
1688
1633
first = FirstOffsetNumber ;
1689
1634
ItemPointerSetMin (& iter_item .iptr );
@@ -1712,8 +1657,16 @@ scanPage(RumState * rumstate, RumScanEntry entry, RumKey *item, Page page,
1712
1657
}
1713
1658
1714
1659
if (bound == -1 )
1660
+ {
1661
+ if (ScanDirectionIsBackward (entry -> scanDirection ))
1662
+ {
1663
+ entry -> offset = maxoff - first ;
1664
+ goto end ;
1665
+ }
1715
1666
return false;
1716
1667
1668
+ }
1669
+
1717
1670
if (found_eq )
1718
1671
{
1719
1672
entry -> offset = bound ;
@@ -1728,6 +1681,7 @@ scanPage(RumState * rumstate, RumScanEntry entry, RumKey *item, Page page,
1728
1681
if (entry -> offset < 0 || entry -> offset >= entry -> nlist )
1729
1682
return false;
1730
1683
1684
+ end :
1731
1685
entry -> curRumKey = entry -> list [entry -> offset ];
1732
1686
return true;
1733
1687
}
0 commit comments