@@ -96,19 +96,49 @@ static void dataPlaceToPageLeafSplit(Buffer buf,
96
96
XLogRecData * * prdata , Page lpage , Page rpage );
97
97
98
98
/*
99
- * Read all TIDs from leaf data page to single uncompressed array.
99
+ * Read TIDs from leaf data page to single uncompressed array. The TIDs are
100
+ * returned in ascending order.
101
+ *
102
+ * advancePast is a hint, indicating that the caller is only interested in
103
+ * TIDs > advancePast. To return all items, use ItemPointerSetMin.
104
+ *
105
+ * Note: This function can still return items smaller than advancePast that
106
+ * are in the same posting list as the items of interest, so the caller must
107
+ * still check all the returned items. But passing it allows this function to
108
+ * skip whole posting lists.
100
109
*/
101
110
ItemPointer
102
- GinDataLeafPageGetItems (Page page , int * nitems )
111
+ GinDataLeafPageGetItems (Page page , int * nitems , ItemPointerData advancePast )
103
112
{
104
113
ItemPointer result ;
105
114
106
115
if (GinPageIsCompressed (page ))
107
116
{
108
- GinPostingList * ptr = GinDataLeafPageGetPostingList (page );
117
+ GinPostingList * seg = GinDataLeafPageGetPostingList (page );
109
118
Size len = GinDataLeafPageGetPostingListSize (page );
119
+ Pointer endptr = ((Pointer ) seg ) + len ;
120
+ GinPostingList * next ;
121
+
122
+ /* Skip to the segment containing advancePast+1 */
123
+ if (ItemPointerIsValid (& advancePast ))
124
+ {
125
+ next = GinNextPostingListSegment (seg );
126
+ while ((Pointer ) next < endptr &&
127
+ ginCompareItemPointers (& next -> first , & advancePast ) <= 0 )
128
+ {
129
+ seg = next ;
130
+ next = GinNextPostingListSegment (seg );
131
+ }
132
+ len = endptr - (Pointer ) seg ;
133
+ }
110
134
111
- result = ginPostingListDecodeAllSegments (ptr , len , nitems );
135
+ if (len > 0 )
136
+ result = ginPostingListDecodeAllSegments (seg , len , nitems );
137
+ else
138
+ {
139
+ result = NULL ;
140
+ * nitems = 0 ;
141
+ }
112
142
}
113
143
else
114
144
{
0 commit comments