@ -8,7 +8,7 @@
* Portions Copyright ( c ) 1994 , Regents of the University of California
*
* IDENTIFICATION
* $ PostgreSQL : pgsql / src / backend / access / gist / gistget . c , v 1.52 .2 .1 2005 / 11 / 22 18 : 23 : 03 momjian Exp $
* $ PostgreSQL : pgsql / src / backend / access / gist / gistget . c , v 1.52 .2 .2 2008 / 08 / 23 10 : 43 : 58 teodor Exp $
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
@ -29,30 +29,23 @@ static bool gistindex_keytest(IndexTuple tuple, IndexScanDesc scan,
static void
killtuple ( Relation r , GISTScanOpaque so , ItemPointer iptr )
{
Buffer buffer = so - > curbuf ;
for ( ; ; )
{
Page p ;
BlockNumber blkno ;
OffsetNumber offset ,
maxoff ;
OffsetNumber offset ;
LockBuffer ( buffer , GIST_SHARE ) ;
p = ( Page ) BufferGetPage ( buffer ) ;
LockBuffer ( so - > curbuf , GIST_SHARE ) ;
p = ( Page ) BufferGetPage ( so - > cur buf) ;
if ( buffer = = so - > curbuf & & XLByteEQ ( so - > stack - > lsn , PageGetLSN ( p ) ) )
if ( XLByteEQ ( so - > stack - > lsn , PageGetLSN ( p ) ) )
{
/* page unchanged, so all is simple */
offset = ItemPointerGetOffsetNumber ( iptr ) ;
PageGetItemId ( p , offset ) - > lp_flags | = LP_DELETE ;
SetBufferCommitInfoNeedsSave ( buffer ) ;
LockBuffer ( buffer , GIST_UNLOCK ) ;
break ;
SetBufferCommitInfoNeedsSave ( so - > curbuf ) ;
}
maxoff = PageGetMaxOffsetNumber ( p ) ;
else
{
OffsetNumber maxoff = PageGetMaxOffsetNumber ( p ) ;
for ( offset = FirstOffsetNumber ; offset < = maxoff ; offset = OffsetNumberNext ( offset ) )
{
@ -62,30 +55,13 @@ killtuple(Relation r, GISTScanOpaque so, ItemPointer iptr)
{
/* found */
PageGetItemId ( p , offset ) - > lp_flags | = LP_DELETE ;
SetBufferCommitInfoNeedsSave ( buffer ) ;
LockBuffer ( buffer , GIST_UNLOCK ) ;
if ( buffer ! = so - > curbuf )
ReleaseBuffer ( buffer ) ;
return ;
SetBufferCommitInfoNeedsSave ( so - > curbuf ) ;
break ;
}
}
/* follow right link */
/*
* ? ? ? is it good ? if tuple dropped by concurrent vacuum , we will read
* all leaf pages . . .
*/
blkno = GistPageGetOpaque ( p ) - > rightlink ;
LockBuffer ( buffer , GIST_UNLOCK ) ;
if ( buffer ! = so - > curbuf )
ReleaseBuffer ( buffer ) ;
if ( blkno = = InvalidBlockNumber )
/* can't found, dropped by somebody else */
return ;
buffer = ReadBuffer ( r , blkno ) ;
}
LockBuffer ( so - > curbuf , GIST_UNLOCK ) ;
}
/*
@ -146,7 +122,6 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
GISTSearchStack * stk ;
IndexTuple it ;
GISTPageOpaque opaque ;
bool resetoffset = false ;
int ntids = 0 ;
so = ( GISTScanOpaque ) scan - > opaque ;
@ -171,6 +146,42 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
return 0 ;
}
/*
* check stored pointers from last visit
*/
if ( so - > nPageData > 0 )
{
while ( ntids < maxtids & & so - > curPageData < so - > nPageData )
{
tids [ ntids ] = scan - > xs_ctup . t_self = so - > pageData [ so - > curPageData ] ;
so - > curPageData + + ;
ntids + + ;
}
if ( ntids = = maxtids )
return ntids ;
/*
* Go to the next page
*/
stk = so - > stack - > next ;
pfree ( so - > stack ) ;
so - > stack = stk ;
/* If we're out of stack entries, we're done */
if ( so - > stack = = NULL )
{
ReleaseBuffer ( so - > curbuf ) ;
so - > curbuf = InvalidBuffer ;
return ntids ;
}
so - > curbuf = ReleaseAndReadBuffer ( so - > curbuf ,
scan - > indexRelation ,
stk - > block ) ;
}
for ( ; ; )
{
/* First of all, we need lock buffer */
@ -178,13 +189,9 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
LockBuffer ( so - > curbuf , GIST_SHARE ) ;
p = BufferGetPage ( so - > curbuf ) ;
opaque = GistPageGetOpaque ( p ) ;
resetoffset = false ;
if ( XLogRecPtrIsInvalid ( so - > stack - > lsn ) | | ! XLByteEQ ( so - > stack - > lsn , PageGetLSN ( p ) ) )
{
/* page changed from last visit or visit first time , reset offset */
/* remember lsn to identify page changed for tuple's killing */
so - > stack - > lsn = PageGetLSN ( p ) ;
resetoffset = true ;
/* check page split, occured from last visit or visit to parent */
if ( ! XLogRecPtrIsInvalid ( so - > stack - > parentlsn ) & &
@ -202,7 +209,6 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
memset ( & ( stk - > lsn ) , 0 , sizeof ( GistNSN ) ) ;
so - > stack - > next = stk ;
}
}
/* if page is empty, then just skip it */
if ( PageIsEmpty ( p ) )
@ -224,24 +230,13 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
continue ;
}
if ( ! GistPageIsLeaf ( p ) | | resetoffset | | ItemPointerIsValid ( & scan - > currentItemData ) = = false )
{
if ( ScanDirectionIsBackward ( dir ) )
n = PageGetMaxOffsetNumber ( p ) ;
else
n = FirstOffsetNumber ;
}
else
{
n = ItemPointerGetOffsetNumber ( & ( scan - > currentItemData ) ) ;
if ( ScanDirectionIsBackward ( dir ) )
n = OffsetNumberPrev ( n ) ;
else
n = OffsetNumberNext ( n ) ;
}
/* wonderfull, we can look at page */
so - > nPageData = so - > curPageData = 0 ;
for ( ; ; )
{
@ -249,6 +244,20 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
if ( ! OffsetNumberIsValid ( n ) )
{
while ( ntids < maxtids & & so - > curPageData < so - > nPageData )
{
tids [ ntids ] = scan - > xs_ctup . t_self = so - > pageData [ so - > curPageData ] ;
so - > curPageData + + ;
ntids + + ;
}
if ( ntids = = maxtids )
{
LockBuffer ( so - > curbuf , GIST_UNLOCK ) ;
return ntids ;
}
/*
* We ran out of matching index entries on the current page ,
* so pop the top stack entry and use it to continue the
@ -288,14 +297,8 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
if ( ! ( ignore_killed_tuples & & ItemIdDeleted ( PageGetItemId ( p , n ) ) ) )
{
it = ( IndexTuple ) PageGetItem ( p , PageGetItemId ( p , n ) ) ;
tids [ ntids ] = scan - > xs_ctup . t_self = it - > t_tid ;
ntids + + ;
if ( ntids = = maxtids )
{
LockBuffer ( so - > curbuf , GIST_UNLOCK ) ;
return ntids ;
}
so - > pageData [ so - > nPageData ] = it - > t_tid ;
so - > nPageData + + ;
}
}
else