Refactor the index AM API slightly: move currentItemData and

currentMarkData from IndexScanDesc to the opaque structs for the
AMs that need this information (currently gist and hash).

Patch from Heikki Linnakangas, fixes by Neil Conway.
This commit is contained in:
Neil Conway 2007-01-20 18:43:35 +00:00
parent 978fff7942
commit 2b7334d487
9 changed files with 57 additions and 59 deletions

View File

@ -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.63 2007/01/05 22:19:22 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.64 2007/01/20 18:43:35 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@ -106,8 +106,8 @@ gistgettuple(PG_FUNCTION_ARGS)
* If we have produced an index tuple in the past and the executor has
* informed us we need to mark it as "killed", do so now.
*/
if (scan->kill_prior_tuple && ItemPointerIsValid(&(scan->currentItemData)))
killtuple(scan->indexRelation, so, &(scan->currentItemData));
if (scan->kill_prior_tuple && ItemPointerIsValid(&(so->curpos)))
killtuple(scan->indexRelation, so, &(so->curpos));
/*
* Get the next tuple that matches the search key. If asked to skip killed
@ -138,7 +138,8 @@ gistgetmulti(PG_FUNCTION_ARGS)
* tuples. Returns true iff a matching tuple was found.
*/
static int
gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, bool ignore_killed_tuples)
gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids,
int maxtids, bool ignore_killed_tuples)
{
Page p;
OffsetNumber n;
@ -151,7 +152,7 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
so = (GISTScanOpaque) scan->opaque;
if (ItemPointerIsValid(&scan->currentItemData) == false)
if (ItemPointerIsValid(&so->curpos) == false)
{
/* Being asked to fetch the first entry, so start at the root */
Assert(so->curbuf == InvalidBuffer);
@ -226,7 +227,7 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
}
if (!GistPageIsLeaf(p) || resetoffset ||
!ItemPointerIsValid(&scan->currentItemData))
!ItemPointerIsValid(&so->curpos))
{
if (ScanDirectionIsBackward(dir))
n = PageGetMaxOffsetNumber(p);
@ -235,7 +236,7 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
}
else
{
n = ItemPointerGetOffsetNumber(&(scan->currentItemData));
n = ItemPointerGetOffsetNumber(&(so->curpos));
if (ScanDirectionIsBackward(dir))
n = OffsetNumberPrev(n);
@ -285,7 +286,7 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
* we can efficiently resume the index scan later.
*/
ItemPointerSet(&(scan->currentItemData),
ItemPointerSet(&(so->curpos),
BufferGetBlockNumber(so->curbuf), n);
if (!(ignore_killed_tuples && ItemIdDeleted(PageGetItemId(p, n))))

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.66 2007/01/05 22:19:22 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.67 2007/01/20 18:43:35 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@ -42,12 +42,6 @@ gistrescan(PG_FUNCTION_ARGS)
GISTScanOpaque so;
int i;
/*
* Clear all the pointers.
*/
ItemPointerSetInvalid(&scan->currentItemData);
ItemPointerSetInvalid(&scan->currentMarkData);
so = (GISTScanOpaque) scan->opaque;
if (so != NULL)
{
@ -82,6 +76,12 @@ gistrescan(PG_FUNCTION_ARGS)
scan->opaque = so;
}
/*
* Clear all the pointers.
*/
ItemPointerSetInvalid(&so->curpos);
ItemPointerSetInvalid(&so->markpos);
/* Update scan key, if a new one is given */
if (key && scan->numberOfKeys > 0)
{
@ -111,8 +111,8 @@ gistmarkpos(PG_FUNCTION_ARGS)
*n,
*tmp;
scan->currentMarkData = scan->currentItemData;
so = (GISTScanOpaque) scan->opaque;
so->markpos = so->curpos;
if (so->flags & GS_CURBEFORE)
so->flags |= GS_MRKBEFORE;
else
@ -160,8 +160,8 @@ gistrestrpos(PG_FUNCTION_ARGS)
*n,
*tmp;
scan->currentItemData = scan->currentMarkData;
so = (GISTScanOpaque) scan->opaque;
so->curpos = so->markpos;
if (so->flags & GS_MRKBEFORE)
so->flags |= GS_CURBEFORE;
else

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.92 2007/01/05 22:19:22 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.93 2007/01/20 18:43:35 neilc Exp $
*
* NOTES
* This file contains only the public interface routines.
@ -185,7 +185,7 @@ hashgettuple(PG_FUNCTION_ARGS)
* appropriate direction. If we haven't done so yet, we call a routine to
* get the first item in the scan.
*/
if (ItemPointerIsValid(&(scan->currentItemData)))
if (ItemPointerIsValid(&(so->hashso_curpos)))
{
/*
* Check to see if we should kill the previously-fetched tuple.
@ -195,7 +195,7 @@ hashgettuple(PG_FUNCTION_ARGS)
/*
* Yes, so mark it by setting the LP_DELETE bit in the item flags.
*/
offnum = ItemPointerGetOffsetNumber(&(scan->currentItemData));
offnum = ItemPointerGetOffsetNumber(&(so->hashso_curpos));
page = BufferGetPage(so->hashso_curbuf);
PageGetItemId(page, offnum)->lp_flags |= LP_DELETE;
@ -222,7 +222,7 @@ hashgettuple(PG_FUNCTION_ARGS)
{
while (res)
{
offnum = ItemPointerGetOffsetNumber(&(scan->currentItemData));
offnum = ItemPointerGetOffsetNumber(&(so->hashso_curpos));
page = BufferGetPage(so->hashso_curbuf);
if (!ItemIdDeleted(PageGetItemId(page, offnum)))
break;
@ -269,7 +269,7 @@ hashgetmulti(PG_FUNCTION_ARGS)
/*
* Start scan, or advance to next tuple.
*/
if (ItemPointerIsValid(&(scan->currentItemData)))
if (ItemPointerIsValid(&(so->hashso_curpos)))
res = _hash_next(scan, ForwardScanDirection);
else
res = _hash_first(scan, ForwardScanDirection);
@ -284,7 +284,7 @@ hashgetmulti(PG_FUNCTION_ARGS)
Page page;
OffsetNumber offnum;
offnum = ItemPointerGetOffsetNumber(&(scan->currentItemData));
offnum = ItemPointerGetOffsetNumber(&(so->hashso_curpos));
page = BufferGetPage(so->hashso_curbuf);
if (!ItemIdDeleted(PageGetItemId(page, offnum)))
break;
@ -325,6 +325,10 @@ hashbeginscan(PG_FUNCTION_ARGS)
so->hashso_bucket_valid = false;
so->hashso_bucket_blkno = 0;
so->hashso_curbuf = so->hashso_mrkbuf = InvalidBuffer;
/* set positions invalid (this will cause _hash_first call) */
ItemPointerSetInvalid(&(so->hashso_curpos));
ItemPointerSetInvalid(&(so->hashso_mrkpos));
scan->opaque = so;
/* register scan in case we change pages it's using */
@ -360,11 +364,11 @@ hashrescan(PG_FUNCTION_ARGS)
if (so->hashso_bucket_blkno)
_hash_droplock(rel, so->hashso_bucket_blkno, HASH_SHARE);
so->hashso_bucket_blkno = 0;
}
/* set positions invalid (this will cause _hash_first call) */
ItemPointerSetInvalid(&(scan->currentItemData));
ItemPointerSetInvalid(&(scan->currentMarkData));
/* set positions invalid (this will cause _hash_first call) */
ItemPointerSetInvalid(&(so->hashso_curpos));
ItemPointerSetInvalid(&(so->hashso_mrkpos));
}
/* Update scan key, if a new one is given */
if (scankey && scan->numberOfKeys > 0)
@ -406,10 +410,6 @@ hashendscan(PG_FUNCTION_ARGS)
_hash_droplock(rel, so->hashso_bucket_blkno, HASH_SHARE);
so->hashso_bucket_blkno = 0;
/* be tidy */
ItemPointerSetInvalid(&(scan->currentItemData));
ItemPointerSetInvalid(&(scan->currentMarkData));
pfree(so);
scan->opaque = NULL;
@ -430,14 +430,14 @@ hashmarkpos(PG_FUNCTION_ARGS)
if (BufferIsValid(so->hashso_mrkbuf))
_hash_dropbuf(rel, so->hashso_mrkbuf);
so->hashso_mrkbuf = InvalidBuffer;
ItemPointerSetInvalid(&(scan->currentMarkData));
ItemPointerSetInvalid(&(so->hashso_mrkpos));
/* bump pin count on currentItemData and copy to currentMarkData */
if (ItemPointerIsValid(&(scan->currentItemData)))
/* bump pin count on current buffer and copy to marked buffer */
if (ItemPointerIsValid(&(so->hashso_curpos)))
{
IncrBufferRefCount(so->hashso_curbuf);
so->hashso_mrkbuf = so->hashso_curbuf;
scan->currentMarkData = scan->currentItemData;
so->hashso_mrkpos = so->hashso_curpos;
}
PG_RETURN_VOID();
@ -457,14 +457,14 @@ hashrestrpos(PG_FUNCTION_ARGS)
if (BufferIsValid(so->hashso_curbuf))
_hash_dropbuf(rel, so->hashso_curbuf);
so->hashso_curbuf = InvalidBuffer;
ItemPointerSetInvalid(&(scan->currentItemData));
ItemPointerSetInvalid(&(so->hashso_curpos));
/* bump pin count on currentMarkData and copy to currentItemData */
if (ItemPointerIsValid(&(scan->currentMarkData)))
/* bump pin count on marked buffer and copy to current buffer */
if (ItemPointerIsValid(&(so->hashso_mrkpos)))
{
IncrBufferRefCount(so->hashso_mrkbuf);
so->hashso_curbuf = so->hashso_mrkbuf;
scan->currentItemData = scan->currentMarkData;
so->hashso_curpos = so->hashso_mrkpos;
}
PG_RETURN_VOID();

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/hash/hashsearch.c,v 1.46 2007/01/05 22:19:22 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/hash/hashsearch.c,v 1.47 2007/01/20 18:43:35 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@ -21,7 +21,7 @@
/*
* _hash_next() -- Get the next item in a scan.
*
* On entry, we have a valid currentItemData in the scan, and a
* On entry, we have a valid hashso_curpos in the scan, and a
* pin and read lock on the page that contains that item.
* We find the next item in the scan, if any.
* On success exit, we have the page containing the next item
@ -49,7 +49,7 @@ _hash_next(IndexScanDesc scan, ScanDirection dir)
return false;
/* if we're here, _hash_step found a valid tuple */
current = &(scan->currentItemData);
current = &(so->hashso_curpos);
offnum = ItemPointerGetOffsetNumber(current);
_hash_checkpage(rel, buf, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
page = BufferGetPage(buf);
@ -129,7 +129,7 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
pgstat_count_index_scan(&scan->xs_pgstat_info);
current = &(scan->currentItemData);
current = &(so->hashso_curpos);
ItemPointerSetInvalid(current);
/*
@ -224,7 +224,7 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
* _hash_step() -- step to the next valid item in a scan in the bucket.
*
* If no valid record exists in the requested direction, return
* false. Else, return true and set the CurrentItemData for the
* false. Else, return true and set the hashso_curpos for the
* scan to the right thing.
*
* 'bufP' points to the current buffer, which is pinned and read-locked.
@ -245,7 +245,7 @@ _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir)
BlockNumber blkno;
IndexTuple itup;
current = &(scan->currentItemData);
current = &(so->hashso_curpos);
buf = *bufP;
_hash_checkpage(rel, buf, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.60 2007/01/05 22:19:22 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.61 2007/01/20 18:43:35 neilc Exp $
*
* NOTES
* many of the old access method routines have been turned into
@ -92,9 +92,6 @@ RelationGetIndexScan(Relation indexRelation,
scan->opaque = NULL;
ItemPointerSetInvalid(&scan->currentItemData);
ItemPointerSetInvalid(&scan->currentMarkData);
ItemPointerSetInvalid(&scan->xs_ctup.t_self);
scan->xs_ctup.t_data = NULL;
scan->xs_cbuf = InvalidBuffer;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.25 2007/01/05 22:19:51 momjian Exp $
* $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.26 2007/01/20 18:43:35 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@ -72,7 +72,9 @@ typedef struct GISTScanOpaqueData
GISTSTATE *giststate;
MemoryContext tempCxt;
Buffer curbuf;
ItemPointerData curpos;
Buffer markbuf;
ItemPointerData markpos;
} GISTScanOpaqueData;
typedef GISTScanOpaqueData *GISTScanOpaque;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/access/hash.h,v 1.74 2007/01/05 22:19:51 momjian Exp $
* $PostgreSQL: pgsql/src/include/access/hash.h,v 1.75 2007/01/20 18:43:35 neilc Exp $
*
* NOTES
* modeled after Margo Seltzer's hash implementation for unix.
@ -97,6 +97,10 @@ typedef struct HashScanOpaqueData
*/
Buffer hashso_curbuf;
Buffer hashso_mrkbuf;
/* Current and marked position of the scan */
ItemPointerData hashso_curpos;
ItemPointerData hashso_mrkpos;
} HashScanOpaqueData;
typedef HashScanOpaqueData *HashScanOpaque;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.108 2007/01/09 02:14:15 tgl Exp $
* $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.109 2007/01/20 18:43:35 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@ -390,9 +390,6 @@ typedef BTStackData *BTStack;
* items were killed, we re-lock the page to mark them killed, then unlock.
* Finally we drop the pin and step to the next page in the appropriate
* direction.
*
* NOTE: in this implementation, btree does not use or set the
* currentItemData and currentMarkData fields of IndexScanDesc at all.
*/
typedef struct BTScanPosItem /* what we remember about each match */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.51 2007/01/05 22:19:51 momjian Exp $
* $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.52 2007/01/20 18:43:35 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@ -69,9 +69,6 @@ typedef struct IndexScanDescData
/* index access method's private state */
void *opaque; /* access-method-specific info */
/* these fields are used by some but not all AMs: */
ItemPointerData currentItemData; /* current index pointer */
ItemPointerData currentMarkData; /* marked position, if any */
/*
* xs_ctup/xs_cbuf are valid after a successful index_getnext. After