Commit bdadc9bf authored by Tom Lane's avatar Tom Lane

Remove RelationGetBufferWithBuffer(), which is horribly confused about

appropriate pin-count manipulation, and instead use ReleaseAndReadBuffer.
Make use of the fact that the passed-in buffer (if there is one) must
be pinned to avoid grabbing the bufmgr spinlock when we are able to
return this same buffer.  Eliminate unnecessary 'previous tuple' and
'next tuple' fields of HeapScanDesc and IndexScanDesc, thereby removing
a whole lot of bookkeeping from heap_getnext() and related routines.
parent 32479891
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.35 2001/05/31 18:16:54 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.36 2001/06/09 18:16:55 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -83,13 +83,8 @@ gistrescan(PG_FUNCTION_ARGS) ...@@ -83,13 +83,8 @@ gistrescan(PG_FUNCTION_ARGS)
/* /*
* Clear all the pointers. * Clear all the pointers.
*/ */
ItemPointerSetInvalid(&s->previousItemData);
ItemPointerSetInvalid(&s->currentItemData); ItemPointerSetInvalid(&s->currentItemData);
ItemPointerSetInvalid(&s->nextItemData);
ItemPointerSetInvalid(&s->previousMarkData);
ItemPointerSetInvalid(&s->currentMarkData); ItemPointerSetInvalid(&s->currentMarkData);
ItemPointerSetInvalid(&s->nextMarkData);
/* /*
* Set flags. * Set flags.
......
...@@ -8,11 +8,10 @@ ...@@ -8,11 +8,10 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.117 2001/05/17 15:55:23 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.118 2001/06/09 18:16:55 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
* heapgettup - fetch next heap tuple from a scan
* heap_open - open a heap relation by relationId * heap_open - open a heap relation by relationId
* heap_openr - open a heap relation by name * heap_openr - open a heap relation by name
* heap_open[r]_nofail - same, but return NULL on failure instead of elog * heap_open[r]_nofail - same, but return NULL on failure instead of elog
...@@ -33,60 +32,20 @@ ...@@ -33,60 +32,20 @@
* the POSTGRES heap access method used for all POSTGRES * the POSTGRES heap access method used for all POSTGRES
* relations. * relations.
* *
* OLD COMMENTS
* struct relscan hints: (struct should be made AM independent?)
*
* rs_ctid is the tid of the last tuple returned by getnext.
* rs_ptid and rs_ntid are the tids of the previous and next tuples
* returned by getnext, respectively. NULL indicates an end of
* scan (either direction); NON indicates an unknow value.
*
* possible combinations:
* rs_p rs_c rs_n interpretation
* NULL NULL NULL empty scan
* NULL NULL NON at begining of scan
* NULL NULL t1 at begining of scan (with cached tid)
* NON NULL NULL at end of scan
* t1 NULL NULL at end of scan (with cached tid)
* NULL t1 NULL just returned only tuple
* NULL t1 NON just returned first tuple
* NULL t1 t2 returned first tuple (with cached tid)
* NON t1 NULL just returned last tuple
* t2 t1 NULL returned last tuple (with cached tid)
* t1 t2 NON in the middle of a forward scan
* NON t2 t1 in the middle of a reverse scan
* ti tj tk in the middle of a scan (w cached tid)
*
* Here NULL is ...tup == NULL && ...buf == InvalidBuffer,
* and NON is ...tup == NULL && ...buf == UnknownBuffer.
*
* Currently, the NONTID values are not cached with their actual
* values by getnext. Values may be cached by markpos since it stores
* all three tids.
*
* NOTE: the calls to elog() must stop. Should decide on an interface
* between the general and specific AM calls.
*
* XXX probably do not need a free tuple routine for heaps.
* Huh? Free tuple is not necessary for tuples returned by scans, but
* is necessary for tuples which are returned by
* RelationGetTupleByItemPointer. -hirohama
*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "access/hio.h" #include "access/hio.h"
#include "access/tuptoaster.h" #include "access/tuptoaster.h"
#include "access/valid.h" #include "access/valid.h"
#include "access/xlogutils.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "utils/inval.h" #include "utils/inval.h"
#include "utils/relcache.h" #include "utils/relcache.h"
#include "access/xlogutils.h"
XLogRecPtr log_heap_move(Relation reln, Buffer oldbuf, ItemPointerData from, XLogRecPtr log_heap_move(Relation reln, Buffer oldbuf, ItemPointerData from,
Buffer newbuf, HeapTuple newtup); Buffer newbuf, HeapTuple newtup);
...@@ -116,7 +75,6 @@ initscan(HeapScanDesc scan, ...@@ -116,7 +75,6 @@ initscan(HeapScanDesc scan,
unsigned nkeys, unsigned nkeys,
ScanKey key) ScanKey key)
{ {
/* /*
* Make sure we have up-to-date idea of number of blocks in relation. * Make sure we have up-to-date idea of number of blocks in relation.
* It is sufficient to do this once at scan start, since any tuples * It is sufficient to do this once at scan start, since any tuples
...@@ -125,50 +83,12 @@ initscan(HeapScanDesc scan, ...@@ -125,50 +83,12 @@ initscan(HeapScanDesc scan,
*/ */
relation->rd_nblocks = RelationGetNumberOfBlocks(relation); relation->rd_nblocks = RelationGetNumberOfBlocks(relation);
if (relation->rd_nblocks == 0) scan->rs_ctup.t_datamcxt = NULL;
{ scan->rs_ctup.t_data = NULL;
scan->rs_cbuf = InvalidBuffer;
/*
* relation is empty
*/
scan->rs_ntup.t_datamcxt = scan->rs_ctup.t_datamcxt =
scan->rs_ptup.t_datamcxt = NULL;
scan->rs_ntup.t_data = scan->rs_ctup.t_data =
scan->rs_ptup.t_data = NULL;
scan->rs_nbuf = scan->rs_cbuf = scan->rs_pbuf = InvalidBuffer;
}
else if (atend)
{
/*
* reverse scan
*/
scan->rs_ntup.t_datamcxt = scan->rs_ctup.t_datamcxt = NULL;
scan->rs_ntup.t_data = scan->rs_ctup.t_data = NULL;
scan->rs_nbuf = scan->rs_cbuf = InvalidBuffer;
scan->rs_ptup.t_datamcxt = NULL;
scan->rs_ptup.t_data = NULL;
scan->rs_pbuf = UnknownBuffer;
}
else
{
/*
* forward scan
*/
scan->rs_ctup.t_datamcxt = scan->rs_ptup.t_datamcxt = NULL;
scan->rs_ctup.t_data = scan->rs_ptup.t_data = NULL;
scan->rs_cbuf = scan->rs_pbuf = InvalidBuffer;
scan->rs_ntup.t_datamcxt = NULL;
scan->rs_ntup.t_data = NULL;
scan->rs_nbuf = UnknownBuffer;
} /* invalid too */
/* we don't have a marked position... */ /* we don't have a marked position... */
ItemPointerSetInvalid(&(scan->rs_mptid));
ItemPointerSetInvalid(&(scan->rs_mctid)); ItemPointerSetInvalid(&(scan->rs_mctid));
ItemPointerSetInvalid(&(scan->rs_mntid));
ItemPointerSetInvalid(&(scan->rs_mcd));
/* /*
* copy the scan key, if appropriate * copy the scan key, if appropriate
...@@ -177,62 +97,22 @@ initscan(HeapScanDesc scan, ...@@ -177,62 +97,22 @@ initscan(HeapScanDesc scan,
memmove(scan->rs_key, key, nkeys * sizeof(ScanKeyData)); memmove(scan->rs_key, key, nkeys * sizeof(ScanKeyData));
} }
/* ----------------
* unpinscan - code common to heap_rescan and heap_endscan
* ----------------
*/
static void
unpinscan(HeapScanDesc scan)
{
if (BufferIsValid(scan->rs_pbuf))
ReleaseBuffer(scan->rs_pbuf);
/*
* Scan will pin buffer once for each non-NULL tuple pointer (ptup,
* ctup, ntup), so they have to be unpinned multiple times.
*/
if (BufferIsValid(scan->rs_cbuf))
ReleaseBuffer(scan->rs_cbuf);
if (BufferIsValid(scan->rs_nbuf))
ReleaseBuffer(scan->rs_nbuf);
/*
* we don't bother to clear rs_pbuf etc --- caller must reinitialize
* them if scan descriptor is not being deleted.
*/
}
/* ------------------------------------------
* nextpage
*
* figure out the next page to scan after the current page
* taking into account of possible adjustment of degrees of
* parallelism
* ------------------------------------------
*/
static int
nextpage(int page, int dir)
{
return (dir < 0) ? page - 1 : page + 1;
}
/* ---------------- /* ----------------
* heapgettup - fetch next heap tuple * heapgettup - fetch next heap tuple
* *
* routine used by heap_getnext() which does most of the * routine used by heap_getnext() which does most of the
* real work in scanning tuples. * real work in scanning tuples.
* *
* The scan routines handle their own buffer lock/unlocking, so * The passed-in *buffer must be either InvalidBuffer or the pinned
* there is no reason to request the buffer number unless * current page of the scan. If we have to move to another page,
* to want to perform some other operation with the result, * we will unpin this buffer (if valid). On return, *buffer is either
* like pass it to another function. * InvalidBuffer or the ID of a pinned buffer.
* ---------------- * ----------------
*/ */
static void static void
heapgettup(Relation relation, heapgettup(Relation relation,
HeapTuple tuple,
int dir, int dir,
HeapTuple tuple,
Buffer *buffer, Buffer *buffer,
Snapshot snapshot, Snapshot snapshot,
int nkeys, int nkeys,
...@@ -245,8 +125,7 @@ heapgettup(Relation relation, ...@@ -245,8 +125,7 @@ heapgettup(Relation relation,
int lines; int lines;
OffsetNumber lineoff; OffsetNumber lineoff;
int linesleft; int linesleft;
ItemPointer tid = (tuple->t_data == NULL) ? ItemPointer tid;
(ItemPointer) NULL : &(tuple->t_self);
/* /*
* increment access statistics * increment access statistics
...@@ -254,6 +133,8 @@ heapgettup(Relation relation, ...@@ -254,6 +133,8 @@ heapgettup(Relation relation,
IncrHeapAccessStat(local_heapgettup); IncrHeapAccessStat(local_heapgettup);
IncrHeapAccessStat(global_heapgettup); IncrHeapAccessStat(global_heapgettup);
tid = (tuple->t_data == NULL) ? (ItemPointer) NULL : &(tuple->t_self);
/* /*
* debugging stuff * debugging stuff
* *
...@@ -280,7 +161,10 @@ heapgettup(Relation relation, ...@@ -280,7 +161,10 @@ heapgettup(Relation relation,
#endif /* !defined(HEAPDEBUGALL) */ #endif /* !defined(HEAPDEBUGALL) */
if (!ItemPointerIsValid(tid)) if (!ItemPointerIsValid(tid))
{
Assert(!PointerIsValid(tid)); Assert(!PointerIsValid(tid));
tid = NULL;
}
tuple->t_tableOid = relation->rd_id; tuple->t_tableOid = relation->rd_id;
...@@ -289,6 +173,9 @@ heapgettup(Relation relation, ...@@ -289,6 +173,9 @@ heapgettup(Relation relation,
*/ */
if (!(pages = relation->rd_nblocks)) if (!(pages = relation->rd_nblocks))
{ {
if (BufferIsValid(*buffer))
ReleaseBuffer(*buffer);
*buffer = InvalidBuffer;
tuple->t_datamcxt = NULL; tuple->t_datamcxt = NULL;
tuple->t_data = NULL; tuple->t_data = NULL;
return; return;
...@@ -299,22 +186,23 @@ heapgettup(Relation relation, ...@@ -299,22 +186,23 @@ heapgettup(Relation relation,
*/ */
if (!dir) if (!dir)
{ {
/* /*
* ``no movement'' scan direction * ``no movement'' scan direction: refetch same tuple
*/ */
/* assume it is a valid TID XXX */ if (tid == NULL)
if (ItemPointerIsValid(tid) == false)
{ {
if (BufferIsValid(*buffer))
ReleaseBuffer(*buffer);
*buffer = InvalidBuffer; *buffer = InvalidBuffer;
tuple->t_datamcxt = NULL; tuple->t_datamcxt = NULL;
tuple->t_data = NULL; tuple->t_data = NULL;
return; return;
} }
*buffer = RelationGetBufferWithBuffer(relation,
ItemPointerGetBlockNumber(tid),
*buffer);
*buffer = ReleaseAndReadBuffer(*buffer,
relation,
ItemPointerGetBlockNumber(tid),
false);
if (!BufferIsValid(*buffer)) if (!BufferIsValid(*buffer))
elog(ERROR, "heapgettup: failed ReadBuffer"); elog(ERROR, "heapgettup: failed ReadBuffer");
...@@ -333,12 +221,9 @@ heapgettup(Relation relation, ...@@ -333,12 +221,9 @@ heapgettup(Relation relation,
} }
else if (dir < 0) else if (dir < 0)
{ {
/* /*
* reverse scan direction * reverse scan direction
*/ */
if (ItemPointerIsValid(tid) == false)
tid = NULL;
if (tid == NULL) if (tid == NULL)
{ {
page = pages - 1; /* final page */ page = pages - 1; /* final page */
...@@ -349,12 +234,18 @@ heapgettup(Relation relation, ...@@ -349,12 +234,18 @@ heapgettup(Relation relation,
} }
if (page < 0) if (page < 0)
{ {
if (BufferIsValid(*buffer))
ReleaseBuffer(*buffer);
*buffer = InvalidBuffer; *buffer = InvalidBuffer;
tuple->t_datamcxt = NULL;
tuple->t_data = NULL; tuple->t_data = NULL;
return; return;
} }
*buffer = RelationGetBufferWithBuffer(relation, page, *buffer); *buffer = ReleaseAndReadBuffer(*buffer,
relation,
page,
false);
if (!BufferIsValid(*buffer)) if (!BufferIsValid(*buffer))
elog(ERROR, "heapgettup: failed ReadBuffer"); elog(ERROR, "heapgettup: failed ReadBuffer");
...@@ -376,11 +267,10 @@ heapgettup(Relation relation, ...@@ -376,11 +267,10 @@ heapgettup(Relation relation,
} }
else else
{ {
/* /*
* forward scan direction * forward scan direction
*/ */
if (ItemPointerIsValid(tid) == false) if (tid == NULL)
{ {
page = 0; /* first page */ page = 0; /* first page */
lineoff = FirstOffsetNumber; /* first offnum */ lineoff = FirstOffsetNumber; /* first offnum */
...@@ -394,14 +284,18 @@ heapgettup(Relation relation, ...@@ -394,14 +284,18 @@ heapgettup(Relation relation,
if (page >= pages) if (page >= pages)
{ {
if (BufferIsValid(*buffer))
ReleaseBuffer(*buffer);
*buffer = InvalidBuffer; *buffer = InvalidBuffer;
tuple->t_datamcxt = NULL; tuple->t_datamcxt = NULL;
tuple->t_data = NULL; tuple->t_data = NULL;
return; return;
} }
/* page and lineoff now reference the physically next tid */
*buffer = RelationGetBufferWithBuffer(relation, page, *buffer); *buffer = ReleaseAndReadBuffer(*buffer,
relation,
page,
false);
if (!BufferIsValid(*buffer)) if (!BufferIsValid(*buffer))
elog(ERROR, "heapgettup: failed ReadBuffer"); elog(ERROR, "heapgettup: failed ReadBuffer");
...@@ -409,6 +303,8 @@ heapgettup(Relation relation, ...@@ -409,6 +303,8 @@ heapgettup(Relation relation,
dp = (Page) BufferGetPage(*buffer); dp = (Page) BufferGetPage(*buffer);
lines = PageGetMaxOffsetNumber(dp); lines = PageGetMaxOffsetNumber(dp);
/* page and lineoff now reference the physically next tid */
} }
/* 'dir' is now non-zero */ /* 'dir' is now non-zero */
...@@ -469,13 +365,13 @@ heapgettup(Relation relation, ...@@ -469,13 +365,13 @@ heapgettup(Relation relation,
/* /*
* if we get here, it means we've exhausted the items on this page * if we get here, it means we've exhausted the items on this page
* and it's time to move to the next.. * and it's time to move to the next.
*/ */
LockBuffer(*buffer, BUFFER_LOCK_UNLOCK); LockBuffer(*buffer, BUFFER_LOCK_UNLOCK);
page = nextpage(page, dir); page = (dir < 0) ? (page - 1) : (page + 1);
/* /*
* return NULL if we've exhausted all the pages.. * return NULL if we've exhausted all the pages
*/ */
if (page < 0 || page >= pages) if (page < 0 || page >= pages)
{ {
...@@ -487,10 +383,13 @@ heapgettup(Relation relation, ...@@ -487,10 +383,13 @@ heapgettup(Relation relation,
return; return;
} }
*buffer = ReleaseAndReadBuffer(*buffer, relation, page, false); *buffer = ReleaseAndReadBuffer(*buffer,
relation,
page,
false);
if (!BufferIsValid(*buffer)) if (!BufferIsValid(*buffer))
elog(ERROR, "heapgettup: failed ReadBuffer"); elog(ERROR, "heapgettup: failed ReadBuffer");
LockBuffer(*buffer, BUFFER_LOCK_SHARE); LockBuffer(*buffer, BUFFER_LOCK_SHARE);
dp = (Page) BufferGetPage(*buffer); dp = (Page) BufferGetPage(*buffer);
lines = PageGetMaxOffsetNumber((Page) dp); lines = PageGetMaxOffsetNumber((Page) dp);
...@@ -766,7 +665,6 @@ heap_beginscan(Relation relation, ...@@ -766,7 +665,6 @@ heap_beginscan(Relation relation,
scan = (HeapScanDesc) palloc(sizeof(HeapScanDescData)); scan = (HeapScanDesc) palloc(sizeof(HeapScanDescData));
scan->rs_rd = relation; scan->rs_rd = relation;
scan->rs_atend = atend;
scan->rs_snapshot = snapshot; scan->rs_snapshot = snapshot;
scan->rs_nkeys = (short) nkeys; scan->rs_nkeys = (short) nkeys;
...@@ -793,7 +691,6 @@ heap_rescan(HeapScanDesc scan, ...@@ -793,7 +691,6 @@ heap_rescan(HeapScanDesc scan,
bool scanFromEnd, bool scanFromEnd,
ScanKey key) ScanKey key)
{ {
/* /*
* increment access statistics * increment access statistics
*/ */
...@@ -803,12 +700,12 @@ heap_rescan(HeapScanDesc scan, ...@@ -803,12 +700,12 @@ heap_rescan(HeapScanDesc scan,
/* /*
* unpin scan buffers * unpin scan buffers
*/ */
unpinscan(scan); if (BufferIsValid(scan->rs_cbuf))
ReleaseBuffer(scan->rs_cbuf);
/* /*
* reinitialize scan descriptor * reinitialize scan descriptor
*/ */
scan->rs_atend = scanFromEnd;
initscan(scan, scan->rs_rd, scanFromEnd, scan->rs_nkeys, key); initscan(scan, scan->rs_rd, scanFromEnd, scan->rs_nkeys, key);
} }
...@@ -822,7 +719,6 @@ heap_rescan(HeapScanDesc scan, ...@@ -822,7 +719,6 @@ heap_rescan(HeapScanDesc scan,
void void
heap_endscan(HeapScanDesc scan) heap_endscan(HeapScanDesc scan)
{ {
/* /*
* increment access statistics * increment access statistics
*/ */
...@@ -834,7 +730,8 @@ heap_endscan(HeapScanDesc scan) ...@@ -834,7 +730,8 @@ heap_endscan(HeapScanDesc scan)
/* /*
* unpin scan buffers * unpin scan buffers
*/ */
unpinscan(scan); if (BufferIsValid(scan->rs_cbuf))
ReleaseBuffer(scan->rs_cbuf);
/* /*
* decrement relation reference count and free scan descriptor storage * decrement relation reference count and free scan descriptor storage
...@@ -862,38 +759,20 @@ elog(DEBUG, "heap_getnext([%s,nkeys=%d],backw=%d) called", \ ...@@ -862,38 +759,20 @@ elog(DEBUG, "heap_getnext([%s,nkeys=%d],backw=%d) called", \
RelationGetRelationName(scan->rs_rd), scan->rs_nkeys, backw) RelationGetRelationName(scan->rs_rd), scan->rs_nkeys, backw)
#define HEAPDEBUG_2 \ #define HEAPDEBUG_2 \
elog(DEBUG, "heap_getnext called with backw (no tracing yet)")
#define HEAPDEBUG_3 \
elog(DEBUG, "heap_getnext returns NULL at end")
#define HEAPDEBUG_4 \
elog(DEBUG, "heap_getnext valid buffer UNPIN'd")
#define HEAPDEBUG_5 \
elog(DEBUG, "heap_getnext next tuple was cached")
#define HEAPDEBUG_6 \
elog(DEBUG, "heap_getnext returning EOS") elog(DEBUG, "heap_getnext returning EOS")
#define HEAPDEBUG_7 \ #define HEAPDEBUG_3 \
elog(DEBUG, "heap_getnext returning tuple"); elog(DEBUG, "heap_getnext returning tuple");
#else #else
#define HEAPDEBUG_1 #define HEAPDEBUG_1
#define HEAPDEBUG_2 #define HEAPDEBUG_2
#define HEAPDEBUG_3 #define HEAPDEBUG_3
#define HEAPDEBUG_4
#define HEAPDEBUG_5
#define HEAPDEBUG_6
#define HEAPDEBUG_7
#endif /* !defined(HEAPDEBUGALL) */ #endif /* !defined(HEAPDEBUGALL) */
HeapTuple HeapTuple
heap_getnext(HeapScanDesc scandesc, int backw) heap_getnext(HeapScanDesc scan, int backw)
{ {
HeapScanDesc scan = scandesc;
/* /*
* increment access statistics * increment access statistics
*/ */
...@@ -908,165 +787,45 @@ heap_getnext(HeapScanDesc scandesc, int backw) ...@@ -908,165 +787,45 @@ heap_getnext(HeapScanDesc scandesc, int backw)
if (scan == NULL) if (scan == NULL)
elog(ERROR, "heap_getnext: NULL relscan"); elog(ERROR, "heap_getnext: NULL relscan");
/*
* initialize return buffer to InvalidBuffer
*/
HEAPDEBUG_1; /* heap_getnext( info ) */ HEAPDEBUG_1; /* heap_getnext( info ) */
if (backw) if (backw)
{ {
/* /*
* handle reverse scan * handle reverse scan
*/ */
HEAPDEBUG_2; /* heap_getnext called with backw */ heapgettup(scan->rs_rd,
-1,
if (scan->rs_ptup.t_data == scan->rs_ctup.t_data && &(scan->rs_ctup),
BufferIsInvalid(scan->rs_pbuf)) &(scan->rs_cbuf),
return NULL; scan->rs_snapshot,
scan->rs_nkeys,
/* scan->rs_key);
* Copy the "current" tuple/buffer to "next". Pin/unpin the
* buffers accordingly
*/
if (scan->rs_nbuf != scan->rs_cbuf)
{
if (BufferIsValid(scan->rs_nbuf))
ReleaseBuffer(scan->rs_nbuf);
if (BufferIsValid(scan->rs_cbuf))
IncrBufferRefCount(scan->rs_cbuf);
}
scan->rs_ntup = scan->rs_ctup;
scan->rs_nbuf = scan->rs_cbuf;
if (scan->rs_ptup.t_data != NULL)
{
if (scan->rs_cbuf != scan->rs_pbuf)
{
if (BufferIsValid(scan->rs_cbuf))
ReleaseBuffer(scan->rs_cbuf);
if (BufferIsValid(scan->rs_pbuf))
IncrBufferRefCount(scan->rs_pbuf);
}
scan->rs_ctup = scan->rs_ptup;
scan->rs_cbuf = scan->rs_pbuf;
}
else
{ /* NONTUP */
/*
* Don't release scan->rs_cbuf at this point, because
* heapgettup doesn't increase PrivateRefCount if it is
* already set. On a backward scan, both rs_ctup and rs_ntup
* usually point to the same buffer page, so
* PrivateRefCount[rs_cbuf] should be 2 (or more, if for
* instance ctup is stored in a TupleTableSlot). - 01/09/94
*/
heapgettup(scan->rs_rd,
&(scan->rs_ctup),
-1,
&(scan->rs_cbuf),
scan->rs_snapshot,
scan->rs_nkeys,
scan->rs_key);
}
if (scan->rs_ctup.t_data == NULL && !BufferIsValid(scan->rs_cbuf)) if (scan->rs_ctup.t_data == NULL && !BufferIsValid(scan->rs_cbuf))
{ {
if (BufferIsValid(scan->rs_pbuf)) HEAPDEBUG_2; /* heap_getnext returning EOS */
ReleaseBuffer(scan->rs_pbuf);
scan->rs_ptup.t_datamcxt = NULL;
scan->rs_ptup.t_data = NULL;
scan->rs_pbuf = InvalidBuffer;
return NULL; return NULL;
} }
if (BufferIsValid(scan->rs_pbuf))
ReleaseBuffer(scan->rs_pbuf);
scan->rs_ptup.t_datamcxt = NULL;
scan->rs_ptup.t_data = NULL;
scan->rs_pbuf = UnknownBuffer;
} }
else else
{ {
/* /*
* handle forward scan * handle forward scan
*/ */
if (scan->rs_ctup.t_data == scan->rs_ntup.t_data && heapgettup(scan->rs_rd,
BufferIsInvalid(scan->rs_nbuf)) 1,
{ &(scan->rs_ctup),
HEAPDEBUG_3; /* heap_getnext returns NULL at end */ &(scan->rs_cbuf),
return NULL; scan->rs_snapshot,
} scan->rs_nkeys,
scan->rs_key);
/*
* Copy the "current" tuple/buffer to "previous". Pin/unpin the
* buffers accordingly
*/
if (scan->rs_pbuf != scan->rs_cbuf)
{
if (BufferIsValid(scan->rs_pbuf))
ReleaseBuffer(scan->rs_pbuf);
if (BufferIsValid(scan->rs_cbuf))
IncrBufferRefCount(scan->rs_cbuf);
}
scan->rs_ptup = scan->rs_ctup;
scan->rs_pbuf = scan->rs_cbuf;
if (scan->rs_ntup.t_data != NULL)
{
if (scan->rs_cbuf != scan->rs_nbuf)
{
if (BufferIsValid(scan->rs_cbuf))
ReleaseBuffer(scan->rs_cbuf);
if (BufferIsValid(scan->rs_nbuf))
IncrBufferRefCount(scan->rs_nbuf);
}
scan->rs_ctup = scan->rs_ntup;
scan->rs_cbuf = scan->rs_nbuf;
HEAPDEBUG_5; /* heap_getnext next tuple was cached */
}
else
{ /* NONTUP */
/*
* Don't release scan->rs_cbuf at this point, because
* heapgettup doesn't increase PrivateRefCount if it is
* already set. On a forward scan, both rs_ctup and rs_ptup
* usually point to the same buffer page, so
* PrivateRefCount[rs_cbuf] should be 2 (or more, if for
* instance ctup is stored in a TupleTableSlot). - 01/09/93
*/
heapgettup(scan->rs_rd,
&(scan->rs_ctup),
1,
&scan->rs_cbuf,
scan->rs_snapshot,
scan->rs_nkeys,
scan->rs_key);
}
if (scan->rs_ctup.t_data == NULL && !BufferIsValid(scan->rs_cbuf)) if (scan->rs_ctup.t_data == NULL && !BufferIsValid(scan->rs_cbuf))
{ {
if (BufferIsValid(scan->rs_nbuf)) HEAPDEBUG_2; /* heap_getnext returning EOS */
ReleaseBuffer(scan->rs_nbuf);
scan->rs_ntup.t_datamcxt = NULL;
scan->rs_ntup.t_data = NULL;
scan->rs_nbuf = InvalidBuffer;
HEAPDEBUG_6; /* heap_getnext returning EOS */
return NULL; return NULL;
} }
if (BufferIsValid(scan->rs_nbuf))
ReleaseBuffer(scan->rs_nbuf);
scan->rs_ntup.t_datamcxt = NULL;
scan->rs_ntup.t_data = NULL;
scan->rs_nbuf = UnknownBuffer;
} }
/* /*
...@@ -1074,7 +833,7 @@ heap_getnext(HeapScanDesc scandesc, int backw) ...@@ -1074,7 +833,7 @@ heap_getnext(HeapScanDesc scandesc, int backw)
* to the proper return buffer and return the tuple. * to the proper return buffer and return the tuple.
*/ */
HEAPDEBUG_7; /* heap_getnext returning tuple */ HEAPDEBUG_3; /* heap_getnext returning tuple */
return ((scan->rs_ctup.t_data == NULL) ? NULL : &(scan->rs_ctup)); return ((scan->rs_ctup.t_data == NULL) ? NULL : &(scan->rs_ctup));
} }
...@@ -1987,7 +1746,6 @@ l3: ...@@ -1987,7 +1746,6 @@ l3:
void void
heap_markpos(HeapScanDesc scan) heap_markpos(HeapScanDesc scan)
{ {
/* /*
* increment access statistics * increment access statistics
*/ */
...@@ -1996,47 +1754,10 @@ heap_markpos(HeapScanDesc scan) ...@@ -1996,47 +1754,10 @@ heap_markpos(HeapScanDesc scan)
/* Note: no locking manipulations needed */ /* Note: no locking manipulations needed */
if (scan->rs_ptup.t_data == NULL &&
BufferIsUnknown(scan->rs_pbuf))
{ /* == NONTUP */
scan->rs_ptup = scan->rs_ctup;
heapgettup(scan->rs_rd,
&(scan->rs_ptup),
-1,
&scan->rs_pbuf,
scan->rs_snapshot,
scan->rs_nkeys,
scan->rs_key);
}
else if (scan->rs_ntup.t_data == NULL &&
BufferIsUnknown(scan->rs_nbuf))
{ /* == NONTUP */
scan->rs_ntup = scan->rs_ctup;
heapgettup(scan->rs_rd,
&(scan->rs_ntup),
1,
&scan->rs_nbuf,
scan->rs_snapshot,
scan->rs_nkeys,
scan->rs_key);
}
/*
* Should not unpin the buffer pages. They may still be in use.
*/
if (scan->rs_ptup.t_data != NULL)
scan->rs_mptid = scan->rs_ptup.t_self;
else
ItemPointerSetInvalid(&scan->rs_mptid);
if (scan->rs_ctup.t_data != NULL) if (scan->rs_ctup.t_data != NULL)
scan->rs_mctid = scan->rs_ctup.t_self; scan->rs_mctid = scan->rs_ctup.t_self;
else else
ItemPointerSetInvalid(&scan->rs_mctid); ItemPointerSetInvalid(&scan->rs_mctid);
if (scan->rs_ntup.t_data != NULL)
scan->rs_mntid = scan->rs_ntup.t_self;
else
ItemPointerSetInvalid(&scan->rs_mntid);
} }
/* ---------------- /* ----------------
...@@ -2048,10 +1769,6 @@ heap_markpos(HeapScanDesc scan) ...@@ -2048,10 +1769,6 @@ heap_markpos(HeapScanDesc scan)
* cause the added tuples to be visible when the scan continues. * cause the added tuples to be visible when the scan continues.
* Problems also arise if the TID's are rearranged!!! * Problems also arise if the TID's are rearranged!!!
* *
* Now pins buffer once for each valid tuple pointer (rs_ptup,
* rs_ctup, rs_ntup) referencing it.
* - 01/13/94
*
* XXX might be better to do direct access instead of * XXX might be better to do direct access instead of
* using the generality of heapgettup(). * using the generality of heapgettup().
* *
...@@ -2063,7 +1780,6 @@ heap_markpos(HeapScanDesc scan) ...@@ -2063,7 +1780,6 @@ heap_markpos(HeapScanDesc scan)
void void
heap_restrpos(HeapScanDesc scan) heap_restrpos(HeapScanDesc scan)
{ {
/* /*
* increment access statistics * increment access statistics
*/ */
...@@ -2074,31 +1790,12 @@ heap_restrpos(HeapScanDesc scan) ...@@ -2074,31 +1790,12 @@ heap_restrpos(HeapScanDesc scan)
/* Note: no locking manipulations needed */ /* Note: no locking manipulations needed */
unpinscan(scan); /*
* unpin scan buffers
/* force heapgettup to pin buffer for each loaded tuple */ */
scan->rs_pbuf = InvalidBuffer; if (BufferIsValid(scan->rs_cbuf))
ReleaseBuffer(scan->rs_cbuf);
scan->rs_cbuf = InvalidBuffer; scan->rs_cbuf = InvalidBuffer;
scan->rs_nbuf = InvalidBuffer;
if (!ItemPointerIsValid(&scan->rs_mptid))
{
scan->rs_ptup.t_datamcxt = NULL;
scan->rs_ptup.t_data = NULL;
}
else
{
scan->rs_ptup.t_self = scan->rs_mptid;
scan->rs_ptup.t_datamcxt = NULL;
scan->rs_ptup.t_data = (HeapTupleHeader) 0x1; /* for heapgettup */
heapgettup(scan->rs_rd,
&(scan->rs_ptup),
0,
&(scan->rs_pbuf),
false,
0,
(ScanKey) NULL);
}
if (!ItemPointerIsValid(&scan->rs_mctid)) if (!ItemPointerIsValid(&scan->rs_mctid))
{ {
...@@ -2111,29 +1808,10 @@ heap_restrpos(HeapScanDesc scan) ...@@ -2111,29 +1808,10 @@ heap_restrpos(HeapScanDesc scan)
scan->rs_ctup.t_datamcxt = NULL; scan->rs_ctup.t_datamcxt = NULL;
scan->rs_ctup.t_data = (HeapTupleHeader) 0x1; /* for heapgettup */ scan->rs_ctup.t_data = (HeapTupleHeader) 0x1; /* for heapgettup */
heapgettup(scan->rs_rd, heapgettup(scan->rs_rd,
&(scan->rs_ctup),
0, 0,
&(scan->rs_ctup),
&(scan->rs_cbuf), &(scan->rs_cbuf),
false, scan->rs_snapshot,
0,
(ScanKey) NULL);
}
if (!ItemPointerIsValid(&scan->rs_mntid))
{
scan->rs_ntup.t_datamcxt = NULL;
scan->rs_ntup.t_data = NULL;
}
else
{
scan->rs_ntup.t_datamcxt = NULL;
scan->rs_ntup.t_self = scan->rs_mntid;
scan->rs_ntup.t_data = (HeapTupleHeader) 0x1; /* for heapgettup */
heapgettup(scan->rs_rd,
&(scan->rs_ntup),
0,
&scan->rs_nbuf,
false,
0, 0,
(ScanKey) NULL); (ScanKey) NULL);
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.26 2001/01/24 19:42:48 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.27 2001/06/09 18:16:56 tgl Exp $
* *
* NOTES * NOTES
* many of the old access method routines have been turned into * many of the old access method routines have been turned into
...@@ -107,12 +107,8 @@ RelationGetIndexScan(Relation relation, ...@@ -107,12 +107,8 @@ RelationGetIndexScan(Relation relation,
scan->opaque = NULL; scan->opaque = NULL;
scan->numberOfKeys = numberOfKeys; scan->numberOfKeys = numberOfKeys;
ItemPointerSetInvalid(&scan->previousItemData);
ItemPointerSetInvalid(&scan->currentItemData); ItemPointerSetInvalid(&scan->currentItemData);
ItemPointerSetInvalid(&scan->nextItemData);
ItemPointerSetInvalid(&scan->previousMarkData);
ItemPointerSetInvalid(&scan->currentMarkData); ItemPointerSetInvalid(&scan->currentMarkData);
ItemPointerSetInvalid(&scan->nextMarkData);
/* /*
* mark cached function lookup data invalid; it will be set on first * mark cached function lookup data invalid; it will be set on first
...@@ -176,9 +172,7 @@ IndexScanRestart(IndexScanDesc scan, ...@@ -176,9 +172,7 @@ IndexScanRestart(IndexScanDesc scan,
if (!IndexScanIsValid(scan)) if (!IndexScanIsValid(scan))
elog(ERROR, "IndexScanRestart: invalid scan"); elog(ERROR, "IndexScanRestart: invalid scan");
ItemPointerSetInvalid(&scan->previousItemData);
ItemPointerSetInvalid(&scan->currentItemData); ItemPointerSetInvalid(&scan->currentItemData);
ItemPointerSetInvalid(&scan->nextItemData);
if (RelationGetNumberOfBlocks(scan->relation) == 0) if (RelationGetNumberOfBlocks(scan->relation) == 0)
scan->flags = ScanUnmarked; scan->flags = ScanUnmarked;
...@@ -213,37 +207,7 @@ IndexScanRestart(IndexScanDesc scan, ...@@ -213,37 +207,7 @@ IndexScanRestart(IndexScanDesc scan,
void void
IndexScanMarkPosition(IndexScanDesc scan) IndexScanMarkPosition(IndexScanDesc scan)
{ {
RetrieveIndexResult result;
if (scan->flags & ScanUncheckedPrevious)
{
result = index_getnext(scan, BackwardScanDirection);
if (result != NULL)
{
scan->previousItemData = result->index_iptr;
pfree(result);
}
else
ItemPointerSetInvalid(&scan->previousItemData);
}
else if (scan->flags & ScanUncheckedNext)
{
result = (RetrieveIndexResult)
index_getnext(scan, ForwardScanDirection);
if (result != NULL)
{
scan->nextItemData = result->index_iptr;
pfree(result);
}
else
ItemPointerSetInvalid(&scan->nextItemData);
}
scan->previousMarkData = scan->previousItemData;
scan->currentMarkData = scan->currentItemData; scan->currentMarkData = scan->currentItemData;
scan->nextMarkData = scan->nextItemData;
scan->flags = 0x0; /* XXX should have a symbolic name */ scan->flags = 0x0; /* XXX should have a symbolic name */
} }
...@@ -269,9 +233,7 @@ IndexScanRestorePosition(IndexScanDesc scan) ...@@ -269,9 +233,7 @@ IndexScanRestorePosition(IndexScanDesc scan)
if (scan->flags & ScanUnmarked) if (scan->flags & ScanUnmarked)
elog(ERROR, "IndexScanRestorePosition: no mark to restore"); elog(ERROR, "IndexScanRestorePosition: no mark to restore");
scan->previousItemData = scan->previousMarkData;
scan->currentItemData = scan->currentMarkData; scan->currentItemData = scan->currentMarkData;
scan->nextItemData = scan->nextMarkData;
scan->flags = 0x0; /* XXX should have a symbolic name */ scan->flags = 0x0; /* XXX should have a symbolic name */
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.36 2001/03/22 03:59:16 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.37 2001/06/09 18:16:56 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -85,13 +85,8 @@ rtrescan(PG_FUNCTION_ARGS) ...@@ -85,13 +85,8 @@ rtrescan(PG_FUNCTION_ARGS)
/* /*
* Clear all the pointers. * Clear all the pointers.
*/ */
ItemPointerSetInvalid(&s->previousItemData);
ItemPointerSetInvalid(&s->currentItemData); ItemPointerSetInvalid(&s->currentItemData);
ItemPointerSetInvalid(&s->nextItemData);
ItemPointerSetInvalid(&s->previousMarkData);
ItemPointerSetInvalid(&s->currentMarkData); ItemPointerSetInvalid(&s->currentMarkData);
ItemPointerSetInvalid(&s->nextMarkData);
/* /*
* Set flags. * Set flags.
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.111 2001/05/12 19:58:27 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.112 2001/06/09 18:16:57 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -96,43 +96,6 @@ static int ReleaseBufferWithBufferLock(Buffer buffer); ...@@ -96,43 +96,6 @@ static int ReleaseBufferWithBufferLock(Buffer buffer);
static int BufferReplace(BufferDesc *bufHdr); static int BufferReplace(BufferDesc *bufHdr);
void PrintBufferDescs(void); void PrintBufferDescs(void);
/* ---------------------------------------------------
* RelationGetBufferWithBuffer
* see if the given buffer is what we want
* if yes, we don't need to bother the buffer manager
* ---------------------------------------------------
*/
Buffer
RelationGetBufferWithBuffer(Relation relation,
BlockNumber blockNumber,
Buffer buffer)
{
BufferDesc *bufHdr;
if (BufferIsValid(buffer))
{
if (!BufferIsLocal(buffer))
{
bufHdr = &BufferDescriptors[buffer - 1];
SpinAcquire(BufMgrLock);
if (bufHdr->tag.blockNum == blockNumber &&
RelFileNodeEquals(bufHdr->tag.rnode, relation->rd_node))
{
SpinRelease(BufMgrLock);
return buffer;
}
return ReadBufferInternal(relation, blockNumber, false, true);
}
else
{
bufHdr = &LocalBufferDescriptors[-buffer - 1];
if (bufHdr->tag.blockNum == blockNumber &&
RelFileNodeEquals(bufHdr->tag.rnode, relation->rd_node))
return buffer;
}
}
return ReadBufferInternal(relation, blockNumber, false, false);
}
/* /*
* ReadBuffer -- returns a buffer containing the requested * ReadBuffer -- returns a buffer containing the requested
...@@ -141,7 +104,8 @@ RelationGetBufferWithBuffer(Relation relation, ...@@ -141,7 +104,8 @@ RelationGetBufferWithBuffer(Relation relation,
* allocate a new block. * allocate a new block.
* *
* Returns: the buffer number for the buffer containing * Returns: the buffer number for the buffer containing
* the block read or NULL on an error. * the block read, or NULL on an error. If successful,
* the returned buffer has been pinned.
* *
* Assume when this function is called, that reln has been * Assume when this function is called, that reln has been
* opened already. * opened already.
...@@ -300,8 +264,8 @@ ReadBufferInternal(Relation reln, BlockNumber blockNum, ...@@ -300,8 +264,8 @@ ReadBufferInternal(Relation reln, BlockNumber blockNum,
} }
/* /*
* BufferAlloc -- Get a buffer from the buffer pool but dont * BufferAlloc -- Get a buffer from the buffer pool but don't
* read it. * read it. If successful, the returned buffer is pinned.
* *
* Returns: descriptor for buffer * Returns: descriptor for buffer
* *
...@@ -684,6 +648,11 @@ WriteNoReleaseBuffer(Buffer buffer) ...@@ -684,6 +648,11 @@ WriteNoReleaseBuffer(Buffer buffer)
* Note: it is OK to pass buffer = InvalidBuffer, indicating that no old * Note: it is OK to pass buffer = InvalidBuffer, indicating that no old
* buffer actually needs to be released. This case is the same as ReadBuffer * buffer actually needs to be released. This case is the same as ReadBuffer
* except for the isExtend option. * except for the isExtend option.
*
* Also, if the passed buffer is valid and already contains the desired block
* number, we simply return it without ever acquiring the spinlock at all.
* Since the passed buffer must be pinned, it's OK to examine its block
* number without getting the lock first.
*/ */
Buffer Buffer
ReleaseAndReadBuffer(Buffer buffer, ReleaseAndReadBuffer(Buffer buffer,
...@@ -698,12 +667,19 @@ ReleaseAndReadBuffer(Buffer buffer, ...@@ -698,12 +667,19 @@ ReleaseAndReadBuffer(Buffer buffer,
if (BufferIsLocal(buffer)) if (BufferIsLocal(buffer))
{ {
Assert(LocalRefCount[-buffer - 1] > 0); Assert(LocalRefCount[-buffer - 1] > 0);
bufHdr = &LocalBufferDescriptors[-buffer - 1];
if (bufHdr->tag.blockNum == blockNum &&
RelFileNodeEquals(bufHdr->tag.rnode, relation->rd_node))
return buffer;
LocalRefCount[-buffer - 1]--; LocalRefCount[-buffer - 1]--;
} }
else else
{ {
bufHdr = &BufferDescriptors[buffer - 1];
Assert(PrivateRefCount[buffer - 1] > 0); Assert(PrivateRefCount[buffer - 1] > 0);
bufHdr = &BufferDescriptors[buffer - 1];
if (bufHdr->tag.blockNum == blockNum &&
RelFileNodeEquals(bufHdr->tag.rnode, relation->rd_node))
return buffer;
if (PrivateRefCount[buffer - 1] > 1) if (PrivateRefCount[buffer - 1] > 1)
PrivateRefCount[buffer - 1]--; PrivateRefCount[buffer - 1]--;
else else
...@@ -1002,7 +978,7 @@ BufferPoolCheckLeak() ...@@ -1002,7 +978,7 @@ BufferPoolCheckLeak()
BufferDesc *buf = &(BufferDescriptors[i - 1]); BufferDesc *buf = &(BufferDescriptors[i - 1]);
elog(NOTICE, elog(NOTICE,
"Buffer Leak: [%03d] (freeNext=%ld, freePrev=%ld, \ "Buffer Leak: [%03d] (freeNext=%d, freePrev=%d, \
relname=%s, blockNum=%d, flags=0x%x, refcount=%d %ld)", relname=%s, blockNum=%d, flags=0x%x, refcount=%d %ld)",
i - 1, buf->freeNext, buf->freePrev, i - 1, buf->freeNext, buf->freePrev,
buf->blind.relname, buf->tag.blockNum, buf->flags, buf->blind.relname, buf->tag.blockNum, buf->flags,
...@@ -1396,7 +1372,7 @@ PrintBufferDescs() ...@@ -1396,7 +1372,7 @@ PrintBufferDescs()
SpinAcquire(BufMgrLock); SpinAcquire(BufMgrLock);
for (i = 0; i < NBuffers; ++i, ++buf) for (i = 0; i < NBuffers; ++i, ++buf)
{ {
elog(DEBUG, "[%02d] (freeNext=%ld, freePrev=%ld, relname=%s, \ elog(DEBUG, "[%02d] (freeNext=%d, freePrev=%d, relname=%s, \
blockNum=%d, flags=0x%x, refcount=%d %ld)", blockNum=%d, flags=0x%x, refcount=%d %ld)",
i, buf->freeNext, buf->freePrev, i, buf->freeNext, buf->freePrev,
buf->blind.relname, buf->tag.blockNum, buf->flags, buf->blind.relname, buf->tag.blockNum, buf->flags,
...@@ -1426,7 +1402,7 @@ PrintPinnedBufs() ...@@ -1426,7 +1402,7 @@ PrintPinnedBufs()
for (i = 0; i < NBuffers; ++i, ++buf) for (i = 0; i < NBuffers; ++i, ++buf)
{ {
if (PrivateRefCount[i] > 0) if (PrivateRefCount[i] > 0)
elog(NOTICE, "[%02d] (freeNext=%ld, freePrev=%ld, relname=%s, \ elog(NOTICE, "[%02d] (freeNext=%d, freePrev=%d, relname=%s, \
blockNum=%d, flags=0x%x, refcount=%d %ld)\n", blockNum=%d, flags=0x%x, refcount=%d %ld)\n",
i, buf->freeNext, buf->freePrev, buf->blind.relname, i, buf->freeNext, buf->freePrev, buf->blind.relname,
buf->tag.blockNum, buf->flags, buf->tag.blockNum, buf->flags,
...@@ -1719,7 +1695,7 @@ IncrBufferRefCount_Debug(char *file, int line, Buffer buffer) ...@@ -1719,7 +1695,7 @@ IncrBufferRefCount_Debug(char *file, int line, Buffer buffer)
{ {
BufferDesc *buf = &BufferDescriptors[buffer - 1]; BufferDesc *buf = &BufferDescriptors[buffer - 1];
fprintf(stderr, "PIN(Incr) %ld relname = %s, blockNum = %d, \ fprintf(stderr, "PIN(Incr) %d relname = %s, blockNum = %d, \
refcount = %ld, file: %s, line: %d\n", refcount = %ld, file: %s, line: %d\n",
buffer, buf->blind.relname, buf->tag.blockNum, buffer, buf->blind.relname, buf->tag.blockNum,
PrivateRefCount[buffer - 1], file, line); PrivateRefCount[buffer - 1], file, line);
...@@ -1737,7 +1713,7 @@ ReleaseBuffer_Debug(char *file, int line, Buffer buffer) ...@@ -1737,7 +1713,7 @@ ReleaseBuffer_Debug(char *file, int line, Buffer buffer)
{ {
BufferDesc *buf = &BufferDescriptors[buffer - 1]; BufferDesc *buf = &BufferDescriptors[buffer - 1];
fprintf(stderr, "UNPIN(Rel) %ld relname = %s, blockNum = %d, \ fprintf(stderr, "UNPIN(Rel) %d relname = %s, blockNum = %d, \
refcount = %ld, file: %s, line: %d\n", refcount = %ld, file: %s, line: %d\n",
buffer, buf->blind.relname, buf->tag.blockNum, buffer, buf->blind.relname, buf->tag.blockNum,
PrivateRefCount[buffer - 1], file, line); PrivateRefCount[buffer - 1], file, line);
...@@ -1765,7 +1741,7 @@ ReleaseAndReadBuffer_Debug(char *file, ...@@ -1765,7 +1741,7 @@ ReleaseAndReadBuffer_Debug(char *file,
{ {
BufferDesc *buf = &BufferDescriptors[buffer - 1]; BufferDesc *buf = &BufferDescriptors[buffer - 1];
fprintf(stderr, "UNPIN(Rel&Rd) %ld relname = %s, blockNum = %d, \ fprintf(stderr, "UNPIN(Rel&Rd) %d relname = %s, blockNum = %d, \
refcount = %ld, file: %s, line: %d\n", refcount = %ld, file: %s, line: %d\n",
buffer, buf->blind.relname, buf->tag.blockNum, buffer, buf->blind.relname, buf->tag.blockNum,
PrivateRefCount[buffer - 1], file, line); PrivateRefCount[buffer - 1], file, line);
...@@ -1774,7 +1750,7 @@ refcount = %ld, file: %s, line: %d\n", ...@@ -1774,7 +1750,7 @@ refcount = %ld, file: %s, line: %d\n",
{ {
BufferDesc *buf = &BufferDescriptors[b - 1]; BufferDesc *buf = &BufferDescriptors[b - 1];
fprintf(stderr, "PIN(Rel&Rd) %ld relname = %s, blockNum = %d, \ fprintf(stderr, "PIN(Rel&Rd) %d relname = %s, blockNum = %d, \
refcount = %ld, file: %s, line: %d\n", refcount = %ld, file: %s, line: %d\n",
b, buf->blind.relname, buf->tag.blockNum, b, buf->blind.relname, buf->tag.blockNum,
PrivateRefCount[b - 1], file, line); PrivateRefCount[b - 1], file, line);
...@@ -2057,7 +2033,7 @@ LockBuffer(Buffer buffer, int mode) ...@@ -2057,7 +2033,7 @@ LockBuffer(Buffer buffer, int mode)
{ {
S_UNLOCK(&(buf->cntx_lock)); S_UNLOCK(&(buf->cntx_lock));
RESUME_INTERRUPTS(); RESUME_INTERRUPTS();
elog(ERROR, "UNLockBuffer: buffer %lu is not locked", buffer); elog(ERROR, "UNLockBuffer: buffer %d is not locked", buffer);
} }
} }
else if (mode == BUFFER_LOCK_SHARE) else if (mode == BUFFER_LOCK_SHARE)
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: relscan.h,v 1.20 2001/01/24 19:43:19 momjian Exp $ * $Id: relscan.h,v 1.21 2001/06/09 18:16:59 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -16,25 +16,16 @@ ...@@ -16,25 +16,16 @@
#include "utils/tqual.h" #include "utils/tqual.h"
typedef ItemPointerData MarkData;
typedef struct HeapScanDescData typedef struct HeapScanDescData
{ {
Relation rs_rd; /* pointer to relation descriptor */ Relation rs_rd; /* pointer to relation descriptor */
HeapTupleData rs_ptup; /* previous tuple in scan */ HeapTupleData rs_ctup; /* current tuple in scan, if any */
HeapTupleData rs_ctup; /* current tuple in scan */ Buffer rs_cbuf; /* current buffer in scan, if any */
HeapTupleData rs_ntup; /* next tuple in scan */ /* NB: if rs_cbuf is not InvalidBuffer, we hold a pin on that buffer */
Buffer rs_pbuf; /* previous buffer in scan */ ItemPointerData rs_mctid; /* marked tid, if any */
Buffer rs_cbuf; /* current buffer in scan */
Buffer rs_nbuf; /* next buffer in scan */
ItemPointerData rs_mptid; /* marked previous tid */
ItemPointerData rs_mctid; /* marked current tid */
ItemPointerData rs_mntid; /* marked next tid */
ItemPointerData rs_mcd; /* marked current delta XXX ??? */
Snapshot rs_snapshot; /* snapshot to see */ Snapshot rs_snapshot; /* snapshot to see */
bool rs_atend; /* restart scan at end? */ uint16 rs_nkeys; /* number of scan keys to select tuples */
uint16 rs_cdelta; /* current delta in chain */
uint16 rs_nkeys; /* number of attributes in keys */
ScanKey rs_key; /* key descriptors */ ScanKey rs_key; /* key descriptors */
} HeapScanDescData; } HeapScanDescData;
...@@ -43,22 +34,24 @@ typedef HeapScanDescData *HeapScanDesc; ...@@ -43,22 +34,24 @@ typedef HeapScanDescData *HeapScanDesc;
typedef struct IndexScanDescData typedef struct IndexScanDescData
{ {
Relation relation; /* relation descriptor */ Relation relation; /* relation descriptor */
void *opaque; /* am-specific slot */ void *opaque; /* access-method-specific info */
ItemPointerData previousItemData; /* previous index pointer */
ItemPointerData currentItemData; /* current index pointer */ ItemPointerData currentItemData; /* current index pointer */
ItemPointerData nextItemData; /* next index pointer */ ItemPointerData currentMarkData; /* marked current pointer */
MarkData previousMarkData; /* marked previous pointer */
MarkData currentMarkData;/* marked current pointer */
MarkData nextMarkData; /* marked next pointer */
uint8 flags; /* scan position flags */ uint8 flags; /* scan position flags */
bool scanFromEnd; /* restart scan at end? */ bool scanFromEnd; /* restart scan at end? */
uint16 numberOfKeys; /* number of key attributes */ uint16 numberOfKeys; /* number of scan keys to select tuples */
ScanKey keyData; /* key descriptor */ ScanKey keyData; /* key descriptors */
FmgrInfo fn_getnext; /* cached lookup info for am's getnext fn */ FmgrInfo fn_getnext; /* cached lookup info for am's getnext fn */
} IndexScanDescData; } IndexScanDescData;
typedef IndexScanDescData *IndexScanDesc; typedef IndexScanDescData *IndexScanDesc;
/* IndexScanDesc flag bits (none of these are actually used currently) */
#define ScanUnmarked 0x01
#define ScanUncheckedPrevious 0x02
#define ScanUncheckedNext 0x04
/* ---------------- /* ----------------
* IndexScanDescPtr is used in the executor where we have to * IndexScanDescPtr is used in the executor where we have to
* keep track of several index scans when using several indices * keep track of several index scans when using several indices
......
...@@ -7,8 +7,7 @@ ...@@ -7,8 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: skey.h,v 1.15 2001/06/01 02:41:36 tgl Exp $ * $Id: skey.h,v 1.16 2001/06/09 18:16:59 tgl Exp $
*
* *
* Note: * Note:
* Needs more accessor/assignment routines. * Needs more accessor/assignment routines.
...@@ -20,6 +19,7 @@ ...@@ -20,6 +19,7 @@
#include "access/attnum.h" #include "access/attnum.h"
#include "fmgr.h" #include "fmgr.h"
typedef struct ScanKeyData typedef struct ScanKeyData
{ {
bits16 sk_flags; /* flags */ bits16 sk_flags; /* flags */
...@@ -38,11 +38,6 @@ typedef ScanKeyData *ScanKey; ...@@ -38,11 +38,6 @@ typedef ScanKeyData *ScanKey;
#define SK_COMMUTE 0x8 /* commute function (not fully supported) */ #define SK_COMMUTE 0x8 /* commute function (not fully supported) */
#define ScanUnmarked 0x01
#define ScanUncheckedPrevious 0x02
#define ScanUncheckedNext 0x04
/* /*
* prototypes for functions in access/common/scankey.c * prototypes for functions in access/common/scankey.c
*/ */
......
...@@ -7,17 +7,22 @@ ...@@ -7,17 +7,22 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: buf.h,v 1.8 2001/01/24 19:43:27 momjian Exp $ * $Id: buf.h,v 1.9 2001/06/09 18:16:59 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef BUF_H #ifndef BUF_H
#define BUF_H #define BUF_H
#define InvalidBuffer (0) /*
#define UnknownBuffer (-99999) * Buffer identifiers.
*
* Zero is invalid, positive is the index of a shared buffer (1..NBuffers),
* negative is the index of a local buffer (-1 .. -NLocBuffer).
*/
typedef int Buffer;
typedef long Buffer; #define InvalidBuffer 0
/* /*
* BufferIsInvalid * BufferIsInvalid
...@@ -25,12 +30,6 @@ typedef long Buffer; ...@@ -25,12 +30,6 @@ typedef long Buffer;
*/ */
#define BufferIsInvalid(buffer) ((buffer) == InvalidBuffer) #define BufferIsInvalid(buffer) ((buffer) == InvalidBuffer)
/*
* BufferIsUnknown
* True iff the buffer is unknown.
*/
#define BufferIsUnknown(buffer) ((buffer) == UnknownBuffer)
/* /*
* BufferIsLocal * BufferIsLocal
* True iff the buffer is local (not visible to other servers). * True iff the buffer is local (not visible to other servers).
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: bufmgr.h,v 1.51 2001/05/12 19:58:28 tgl Exp $ * $Id: bufmgr.h,v 1.52 2001/06/09 18:16:59 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -75,10 +75,6 @@ extern long *LocalRefCount; ...@@ -75,10 +75,6 @@ extern long *LocalRefCount;
* True iff the given buffer number is valid (either as a shared * True iff the given buffer number is valid (either as a shared
* or local buffer). * or local buffer).
* *
* Note:
* BufferIsValid(InvalidBuffer) is False.
* BufferIsValid(UnknownBuffer) is False.
*
* Note: For a long time this was defined the same as BufferIsPinned, * Note: For a long time this was defined the same as BufferIsPinned,
* that is it would say False if you didn't hold a pin on the buffer. * that is it would say False if you didn't hold a pin on the buffer.
* I believe this was bogus and served only to mask logic errors. * I believe this was bogus and served only to mask logic errors.
...@@ -158,8 +154,6 @@ extern long *LocalRefCount; ...@@ -158,8 +154,6 @@ extern long *LocalRefCount;
/* /*
* prototypes for functions in bufmgr.c * prototypes for functions in bufmgr.c
*/ */
extern Buffer RelationGetBufferWithBuffer(Relation relation,
BlockNumber blockNumber, Buffer buffer);
extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum); extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum);
extern int WriteBuffer(Buffer buffer); extern int WriteBuffer(Buffer buffer);
extern int WriteNoReleaseBuffer(Buffer buffer); extern int WriteNoReleaseBuffer(Buffer buffer);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment