@@ -80,14 +80,14 @@ callConsistentFn(RumState *rumstate, RumScanKey key)
8080
8181if (res && key -> attnum == rumstate -> attrnAddToColumn )
8282{
83- int i ;
83+ uint32 i ;
8484
8585/* remember some addinfo value for later ordering by addinfo
8686 from another column */
8787
8888key -> outerAddInfoIsNull = true;
8989
90- for (i = 0 ;i < key -> nuserentries ;i ++ )
90+ for (i = 0 ;i < key -> nuserentries ;i ++ )
9191{
9292if (key -> entryRes [i ]&& key -> addInfoIsNull [0 ]== false)
9393{
@@ -571,6 +571,10 @@ startScanKey(RumState *rumstate, RumScanKey key)
571571key -> isFinished = false;
572572}
573573
574+ /*
575+ * Compare entries position. At first consider isFinished flag, then compare
576+ * item pointers.
577+ */
574578static int
575579cmpEntries (RumScanEntry e1 ,RumScanEntry e2 )
576580{
@@ -670,6 +674,10 @@ startScan(IndexScanDesc scan)
670674
671675if (useFastScan )
672676{
677+ /*
678+ * We are going to use fast scan. Do some preliminaries. Start scan
679+ * of each entry and sort entries by descending item pointers.
680+ */
673681so -> sortedEntries = (RumScanEntry * )palloc (sizeof (RumScanEntry )*
674682so -> totalentries );
675683memcpy (so -> sortedEntries ,so -> entries ,sizeof (RumScanEntry )*
@@ -1237,15 +1245,21 @@ scanGetItemRegular(IndexScanDesc scan, ItemPointer advancePast,
12371245return TRUE;
12381246}
12391247
1248+ /*
1249+ * Finds part of page containing requested item using small index at the end
1250+ * of page.
1251+ */
12401252static bool
1241- scanPage (RumState * rumstate ,RumScanEntry entry ,ItemPointer item ,Page page ,bool equalOk )
1253+ scanPage (RumState * rumstate ,RumScanEntry entry ,ItemPointer item ,Page page ,
1254+ bool equalOk )
12421255{
1243- int j ;
1256+ int j ;
12441257RumKey iter_item ;
1245- Pointer ptr ;
1246- OffsetNumber first = FirstOffsetNumber ,i ,maxoff ;
1247- bool found ;
1248- int cmp ;
1258+ Pointer ptr ;
1259+ OffsetNumber first = FirstOffsetNumber ,
1260+ i ,maxoff ;
1261+ bool found ;
1262+ int cmp ;
12491263
12501264ItemPointerSetMin (& iter_item .iptr );
12511265
@@ -1300,6 +1314,9 @@ scanPage(RumState *rumstate, RumScanEntry entry, ItemPointer item, Page page, bo
13001314return true;
13011315}
13021316
1317+ /*
1318+ * Find item pointer of entry with is greater or equal to given item pointer.
1319+ */
13031320static void
13041321entryFindItem (RumState * rumstate ,RumScanEntry entry ,RumKey * item )
13051322{
@@ -1311,6 +1328,7 @@ entryFindItem(RumState *rumstate, RumScanEntry entry, RumKey *item)
13111328return ;
13121329}
13131330
1331+ /* Try to find in loaded part of page */
13141332if (rumCompareItemPointers (& entry -> list [entry -> nlist - 1 ].iptr ,
13151333& item -> iptr ) >=0 )
13161334{
@@ -1329,13 +1347,13 @@ entryFindItem(RumState *rumstate, RumScanEntry entry, RumKey *item)
13291347}
13301348}
13311349
1332-
13331350if (!BufferIsValid (entry -> buffer ))
13341351{
13351352entry -> isFinished = TRUE;
13361353return ;
13371354}
13381355
1356+ /* Check rest of page */
13391357LockBuffer (entry -> buffer ,RUM_SHARE );
13401358
13411359if (scanPage (rumstate ,entry ,& item -> iptr ,
@@ -1346,6 +1364,7 @@ entryFindItem(RumState *rumstate, RumScanEntry entry, RumKey *item)
13461364return ;
13471365}
13481366
1367+ /* Try to traverse to another leaf page */
13491368entry -> gdi -> btree .items = item ;
13501369entry -> gdi -> btree .curitem = 0 ;
13511370
@@ -1363,6 +1382,7 @@ entryFindItem(RumState *rumstate, RumScanEntry entry, RumKey *item)
13631382return ;
13641383}
13651384
1385+ /* At last try to traverse by right links */
13661386for (;;)
13671387{
13681388/*
@@ -1402,17 +1422,20 @@ entryFindItem(RumState *rumstate, RumScanEntry entry, RumKey *item)
14021422}
14031423}
14041424
1425+ /*
1426+ * Do preConsistent check for all the key where applicable.
1427+ */
14051428static bool
14061429preConsistentCheck (RumScanOpaque so )
14071430{
1408- RumState * rumstate = & so -> rumstate ;
1409- int i ,j ;
1410- bool recheck ;
1431+ RumState * rumstate = & so -> rumstate ;
1432+ uint32 i ,j ;
1433+ bool recheck ;
14111434
14121435for (j = 0 ;j < so -> nkeys ;j ++ )
14131436{
1414- RumScanKey key = & so -> keys [j ];
1415- bool hasFalse = false;
1437+ RumScanKey key = & so -> keys [j ];
1438+ bool hasFalse = false;
14161439
14171440if (key -> orderBy )
14181441continue ;
@@ -1448,29 +1471,43 @@ preConsistentCheck(RumScanOpaque so)
14481471return true;
14491472}
14501473
1474+ /*
1475+ * Shift value of some entry which index in so->sortedEntries is equal or greater
1476+ * to i.
1477+ */
14511478static void
14521479entryShift (int i ,RumScanOpaque so ,bool find )
14531480{
1454- int minIndex = -1 ,j ;
1455- uint32 minPredictNumberResult = 0 ;
1481+ int minIndex = -1 ,
1482+ j ;
1483+ uint32 minPredictNumberResult = 0 ;
14561484RumState * rumstate = & so -> rumstate ;
14571485
1486+ /*
1487+ * It's more efficient to move entry with smallest posting list/tree. So
1488+ * find one.
1489+ */
14581490for (j = i ;j < so -> totalentries ;j ++ )
14591491{
1460- if (minIndex < 0 || so -> sortedEntries [j ]-> predictNumberResult < minPredictNumberResult )
1492+ if (minIndex < 0 ||
1493+ so -> sortedEntries [j ]-> predictNumberResult < minPredictNumberResult )
14611494{
14621495minIndex = j ;
14631496minPredictNumberResult = so -> sortedEntries [j ]-> predictNumberResult ;
14641497}
14651498}
14661499
1500+ /* Do shift of required type */
14671501if (find )
1468- entryFindItem (rumstate ,so -> sortedEntries [minIndex ],& so -> sortedEntries [i - 1 ]-> curItem );
1502+ entryFindItem (rumstate ,so -> sortedEntries [minIndex ],
1503+ & so -> sortedEntries [i - 1 ]-> curItem );
14691504else if (!so -> sortedEntries [minIndex ]-> isFinished )
14701505entryGetItem (rumstate ,so -> sortedEntries [minIndex ]);
14711506
1507+ /* Restore order of so->sortedEntries */
14721508while (minIndex > 0 &&
1473- cmpEntries (so -> sortedEntries [minIndex ],so -> sortedEntries [minIndex - 1 ])> 0 )
1509+ cmpEntries (so -> sortedEntries [minIndex ],
1510+ so -> sortedEntries [minIndex - 1 ])> 0 )
14741511{
14751512RumScanEntry tmp ;
14761513tmp = so -> sortedEntries [minIndex ];
@@ -1480,13 +1517,16 @@ entryShift(int i, RumScanOpaque so, bool find)
14801517}
14811518}
14821519
1520+ /*
1521+ * Get next item pointer using fast scan.
1522+ */
14831523static bool
14841524scanGetItemFast (IndexScanDesc scan ,ItemPointer advancePast ,
1485- ItemPointerData * item ,bool * recheck )
1525+ ItemPointerData * item ,bool * recheck )
14861526{
14871527RumScanOpaque so = (RumScanOpaque )scan -> opaque ;
1488- int i ,j ,k ;
1489- bool preConsistentFalse ,consistentFalse ;
1528+ int i ,j ,k ;
1529+ bool preConsistentFalse ,consistentFalse ;
14901530
14911531if (so -> entriesIncrIndex >=0 )
14921532{
@@ -1496,6 +1536,10 @@ scanGetItemFast(IndexScanDesc scan, ItemPointer advancePast,
14961536
14971537for (;;)
14981538{
1539+ /*
1540+ * Our entries is ordered by descending of item pointers.
1541+ * The first goal is to find border where preConsistent becomes false.
1542+ */
14991543preConsistentFalse = false;
15001544j = 0 ;
15011545k = 0 ;
@@ -1517,6 +1561,10 @@ scanGetItemFast(IndexScanDesc scan, ItemPointer advancePast,
15171561}
15181562}
15191563
1564+ /*
1565+ * If we found false in preConsistent then we can safely move entries
1566+ * which was true in preConsistent argument.
1567+ */
15201568if (so -> sortedEntries [i - 1 ]-> isFinished == TRUE)
15211569return false;
15221570
@@ -1526,6 +1574,7 @@ scanGetItemFast(IndexScanDesc scan, ItemPointer advancePast,
15261574continue ;
15271575}
15281576
1577+ /* Call consistent method */
15291578consistentFalse = false;
15301579for (i = 0 ;i < so -> nkeys ;i ++ )
15311580{
@@ -1563,6 +1612,7 @@ scanGetItemFast(IndexScanDesc scan, ItemPointer advancePast,
15631612if (consistentFalse )
15641613continue ;
15651614
1615+ /* Calculate recheck from each key */
15661616* recheck = false;
15671617for (i = 0 ;i < so -> nkeys ;i ++ )
15681618{
@@ -1586,6 +1636,9 @@ scanGetItemFast(IndexScanDesc scan, ItemPointer advancePast,
15861636return false;
15871637}
15881638
1639+ /*
1640+ * Get next item whether using regular or fast scan.
1641+ */
15891642static bool
15901643scanGetItem (IndexScanDesc scan ,ItemPointer advancePast ,
15911644ItemPointerData * item ,bool * recheck )
@@ -1776,7 +1829,7 @@ collectMatchesForHeapRow(IndexScanDesc scan, pendingPosition *pos)
17761829OffsetNumber attrnum ;
17771830Page page ;
17781831IndexTuple itup ;
1779- int i ,
1832+ uint32 i ,
17801833j ;
17811834
17821835/*
@@ -1997,7 +2050,7 @@ scanPendingInsert(IndexScanDesc scan)
19972050MemoryContext oldCtx ;
19982051bool recheck ,
19992052match ;
2000- int i ;
2053+ uint32 i ;
20012054pendingPosition pos ;
20022055Buffer metabuffer = ReadBuffer (scan -> indexRelation ,RUM_METAPAGE_BLKNO );
20032056BlockNumber blkno ;
@@ -2145,7 +2198,7 @@ keyGetOrdering(RumState *rumstate, MemoryContext tempCtx, RumScanKey key,
21452198ItemPointer iptr )
21462199{
21472200RumScanEntry entry ;
2148- int i ;
2201+ uint32 i ;
21492202
21502203if (key -> useAddToColumn )
21512204{
@@ -2200,7 +2253,7 @@ static void
22002253insertScanItem (RumScanOpaque so ,bool recheck )
22012254{
22022255RumSortItem * item ;
2203- int i ,j ;
2256+ uint32 i ,j ;
22042257
22052258item = (RumSortItem * )
22062259MemoryContextAlloc (rum_tuplesort_get_memorycontext (so -> sortstate ),
@@ -2297,7 +2350,7 @@ rumgettuple(IndexScanDesc scan, ScanDirection direction)
22972350item = rum_tuplesort_getrum (so -> sortstate , true,& should_free );
22982351if (item )
22992352{
2300- int i ,j = 0 ;
2353+ uint32 i ,j = 0 ;
23012354
23022355scan -> xs_ctup .t_self = item -> iptr ;
23032356scan -> xs_recheck = item -> recheck ;