XLogRecData **prdata, Page lpage, Page rpage);
/*
- * Read all TIDs from leaf data page to single uncompressed array.
+ * Read TIDs from leaf data page to single uncompressed array. The TIDs are
+ * returned in ascending order.
+ *
+ * advancePast is a hint, indicating that the caller is only interested in
+ * TIDs > advancePast. To return all items, use ItemPointerSetMin.
+ *
+ * Note: This function can still return items smaller than advancePast that
+ * are in the same posting list as the items of interest, so the caller must
+ * still check all the returned items. But passing it allows this function to
+ * skip whole posting lists.
*/
ItemPointer
-GinDataLeafPageGetItems(Page page, int *nitems)
+GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast)
{
ItemPointer result;
if (GinPageIsCompressed(page))
{
- GinPostingList *ptr = GinDataLeafPageGetPostingList(page);
+ GinPostingList *seg = GinDataLeafPageGetPostingList(page);
Size len = GinDataLeafPageGetPostingListSize(page);
+ Pointer endptr = ((Pointer) seg) + len;
+ GinPostingList *next;
+
+ /* Skip to the segment containing advancePast+1 */
+ if (ItemPointerIsValid(&advancePast))
+ {
+ next = GinNextPostingListSegment(seg);
+ while ((Pointer) next < endptr &&
+ ginCompareItemPointers(&next->first, &advancePast) <= 0)
+ {
+ seg = next;
+ next = GinNextPostingListSegment(seg);
+ }
+ len = endptr - (Pointer) seg;
+ }
- result = ginPostingListDecodeAllSegments(ptr, len, nitems);
+ if (len > 0)
+ result = ginPostingListDecodeAllSegments(seg, len, nitems);
+ else
+ {
+ result = NULL;
+ *nitems = 0;
+ }
}
else
{
BlockNumber rootPostingTree = GinGetPostingTree(itup);
GinBtreeStack *stack;
Page page;
+ ItemPointerData minItem;
/*
* We should unlock entry page before touching posting tree to
/*
* Load the first page into memory.
*/
- entry->list = GinDataLeafPageGetItems(page, &entry->nlist);
+ ItemPointerSetMin(&minItem);
+ entry->list = GinDataLeafPageGetItems(page, &entry->nlist, minItem);
entry->predictNumberResult = stack->predictNumber * entry->nlist;
continue;
}
- entry->list = GinDataLeafPageGetItems(page, &entry->nlist);
+ entry->list = GinDataLeafPageGetItems(page, &entry->nlist, advancePast);
for (i = 0; i < entry->nlist; i++)
{
IndexTuple itup, int *nitems);
/* gindatapage.c */
-extern ItemPointer GinDataLeafPageGetItems(Page page, int *nitems);
+extern ItemPointer GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast);
extern int GinDataLeafPageGetItemsToTbm(Page page, TIDBitmap *tbm);
extern BlockNumber createPostingTree(Relation index,
ItemPointerData *items, uint32 nitems,