Another round of code cleanup on bufmgr. Use BM_VALID flag to keep track
of whether we have successfully read data into a buffer; this makes the error behavior a bit more transparent (IMHO anyway), and also makes it work correctly for local buffers which don't use Start/TerminateBufferIO. Collapse three separate functions for writing a shared buffer into one. This overlaps a bit with cleanups that Neil proposed awhile back, but seems not to have committed yet.
This commit is contained in:
parent
aeee856564
commit
95a03e9cdf
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.63 2004/04/19 23:27:17 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.64 2004/04/21 18:06:30 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -133,11 +133,11 @@ InitBufferPool(void)
|
|||
|
||||
buf->bufNext = i + 1;
|
||||
|
||||
CLEAR_BUFFERTAG(&(buf->tag));
|
||||
CLEAR_BUFFERTAG(buf->tag);
|
||||
buf->buf_id = i;
|
||||
|
||||
buf->data = MAKE_OFFSET(block);
|
||||
buf->flags = (BM_DELETED | BM_VALID);
|
||||
buf->flags = 0;
|
||||
buf->refcount = 0;
|
||||
buf->io_in_progress_lock = LWLockAssign();
|
||||
buf->cntx_lock = LWLockAssign();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -12,7 +12,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.42 2004/04/19 23:27:17 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.43 2004/04/21 18:06:30 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -501,7 +501,7 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag,
|
|||
|
||||
/* Assert that the buffer remembered in cdb_found is the one */
|
||||
/* the buffer manager is currently faulting in */
|
||||
Assert(BUFFERTAGS_EQUAL(&(cdb_found->buf_tag), newTag));
|
||||
Assert(BUFFERTAGS_EQUAL(cdb_found->buf_tag, *newTag));
|
||||
|
||||
if (cdb_replace_index >= 0)
|
||||
{
|
||||
|
@ -513,7 +513,7 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag,
|
|||
Assert(cdb_replace->list == STRAT_LIST_T1 ||
|
||||
cdb_replace->list == STRAT_LIST_T2);
|
||||
Assert(cdb_replace->buf_id == buf->buf_id);
|
||||
Assert(BUFFERTAGS_EQUAL(&(cdb_replace->buf_tag), &(buf->tag)));
|
||||
Assert(BUFFERTAGS_EQUAL(cdb_replace->buf_tag, buf->tag));
|
||||
|
||||
/*
|
||||
* Under normal circumstances we move the evicted T list entry to
|
||||
|
@ -606,7 +606,7 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag,
|
|||
Assert(cdb_replace->list == STRAT_LIST_T1 ||
|
||||
cdb_replace->list == STRAT_LIST_T2);
|
||||
Assert(cdb_replace->buf_id == buf->buf_id);
|
||||
Assert(BUFFERTAGS_EQUAL(&(cdb_replace->buf_tag), &(buf->tag)));
|
||||
Assert(BUFFERTAGS_EQUAL(cdb_replace->buf_tag, buf->tag));
|
||||
|
||||
if (cdb_replace->list == STRAT_LIST_T1)
|
||||
{
|
||||
|
@ -673,7 +673,7 @@ StrategyInvalidateBuffer(BufferDesc *buf)
|
|||
BufferStrategyCDB *cdb;
|
||||
|
||||
/* The buffer cannot be dirty or pinned */
|
||||
Assert(!(buf->flags & BM_DIRTY));
|
||||
Assert(!(buf->flags & BM_DIRTY) || !(buf->flags & BM_VALID));
|
||||
Assert(buf->refcount == 0);
|
||||
|
||||
/*
|
||||
|
@ -695,16 +695,18 @@ StrategyInvalidateBuffer(BufferDesc *buf)
|
|||
* Clear out the CDB's buffer tag and association with the buffer
|
||||
* and add it to the list of unused CDB's
|
||||
*/
|
||||
CLEAR_BUFFERTAG(&(cdb->buf_tag));
|
||||
CLEAR_BUFFERTAG(cdb->buf_tag);
|
||||
cdb->buf_id = -1;
|
||||
cdb->next = StrategyControl->listUnusedCDB;
|
||||
StrategyControl->listUnusedCDB = cdb_id;
|
||||
|
||||
/*
|
||||
* Clear out the buffer's tag and add it to the list of
|
||||
* currently unused buffers.
|
||||
* currently unused buffers. We must do this to ensure that linear
|
||||
* scans of the buffer array don't think the buffer is valid.
|
||||
*/
|
||||
CLEAR_BUFFERTAG(&(buf->tag));
|
||||
CLEAR_BUFFERTAG(buf->tag);
|
||||
buf->flags &= ~(BM_VALID | BM_DIRTY);
|
||||
buf->bufNext = StrategyControl->listFreeBuffers;
|
||||
StrategyControl->listFreeBuffers = buf->buf_id;
|
||||
}
|
||||
|
@ -864,7 +866,7 @@ StrategyInitialize(bool init)
|
|||
{
|
||||
StrategyCDB[i].next = i + 1;
|
||||
StrategyCDB[i].list = STRAT_LIST_UNUSED;
|
||||
CLEAR_BUFFERTAG(&(StrategyCDB[i].buf_tag));
|
||||
CLEAR_BUFFERTAG(StrategyCDB[i].buf_tag);
|
||||
StrategyCDB[i].buf_id = -1;
|
||||
}
|
||||
StrategyCDB[NBuffers * 2 - 1].next = -1;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.52 2004/02/10 01:55:25 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.53 2004/04/21 18:06:30 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -36,19 +36,25 @@ static int nextFreeLocalBuf = 0;
|
|||
/*
|
||||
* LocalBufferAlloc -
|
||||
* allocate a local buffer. We do round robin allocation for now.
|
||||
*
|
||||
* API is similar to bufmgr.c's BufferAlloc, except that we do not need
|
||||
* to have the BufMgrLock since this is all local. Also, IO_IN_PROGRESS
|
||||
* does not get set.
|
||||
*/
|
||||
BufferDesc *
|
||||
LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
||||
{
|
||||
BufferTag newTag; /* identity of requested block */
|
||||
int i;
|
||||
BufferDesc *bufHdr = NULL;
|
||||
BufferDesc *bufHdr;
|
||||
|
||||
INIT_BUFFERTAG(newTag, reln, blockNum);
|
||||
|
||||
/* a low tech search for now -- not optimized for scans */
|
||||
for (i = 0; i < NLocBuffer; i++)
|
||||
{
|
||||
if (LocalBufferDescriptors[i].tag.rnode.relNode ==
|
||||
reln->rd_node.relNode &&
|
||||
LocalBufferDescriptors[i].tag.blockNum == blockNum)
|
||||
bufHdr = &LocalBufferDescriptors[i];
|
||||
if (BUFFERTAGS_EQUAL(bufHdr->tag, newTag))
|
||||
{
|
||||
#ifdef LBDEBUG
|
||||
fprintf(stderr, "LB ALLOC (%u,%d) %d\n",
|
||||
|
@ -56,8 +62,14 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
|||
#endif
|
||||
|
||||
LocalRefCount[i]++;
|
||||
if (bufHdr->flags & BM_VALID)
|
||||
*foundPtr = TRUE;
|
||||
return &LocalBufferDescriptors[i];
|
||||
else
|
||||
{
|
||||
/* Previous read attempt must have failed; try again */
|
||||
*foundPtr = FALSE;
|
||||
}
|
||||
return bufHdr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,6 +79,7 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
|||
#endif
|
||||
|
||||
/* need to get a new buffer (round robin for now) */
|
||||
bufHdr = NULL;
|
||||
for (i = 0; i < NLocBuffer; i++)
|
||||
{
|
||||
int b = (nextFreeLocalBuf + i) % NLocBuffer;
|
||||
|
@ -108,7 +121,7 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
|||
*
|
||||
* Note this path cannot be taken for a buffer that was previously in
|
||||
* use, so it's okay to do it (and possibly error out) before marking
|
||||
* the buffer as valid.
|
||||
* the buffer as not dirty.
|
||||
*/
|
||||
if (bufHdr->data == (SHMEM_OFFSET) 0)
|
||||
{
|
||||
|
@ -135,9 +148,8 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
|||
/*
|
||||
* it's all ours now.
|
||||
*/
|
||||
bufHdr->tag.rnode = reln->rd_node;
|
||||
bufHdr->tag.blockNum = blockNum;
|
||||
bufHdr->flags &= ~BM_DIRTY;
|
||||
bufHdr->tag = newTag;
|
||||
bufHdr->flags &= ~(BM_VALID | BM_DIRTY | BM_JUST_DIRTIED | BM_IO_ERROR);
|
||||
bufHdr->cntxDirty = false;
|
||||
|
||||
*foundPtr = FALSE;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.69 2004/04/19 23:27:17 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.70 2004/04/21 18:06:29 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -24,13 +24,12 @@
|
|||
/*
|
||||
* Flags for buffer descriptors
|
||||
*/
|
||||
#define BM_DIRTY (1 << 0)
|
||||
#define BM_VALID (1 << 1)
|
||||
#define BM_DELETED (1 << 2)
|
||||
#define BM_IO_IN_PROGRESS (1 << 3)
|
||||
#define BM_IO_ERROR (1 << 4)
|
||||
#define BM_JUST_DIRTIED (1 << 5)
|
||||
#define BM_PIN_COUNT_WAITER (1 << 6)
|
||||
#define BM_DIRTY (1 << 0) /* data needs writing */
|
||||
#define BM_VALID (1 << 1) /* data is valid */
|
||||
#define BM_IO_IN_PROGRESS (1 << 2) /* read or write in progress */
|
||||
#define BM_IO_ERROR (1 << 3) /* previous I/O failed */
|
||||
#define BM_JUST_DIRTIED (1 << 4) /* dirtied since write started */
|
||||
#define BM_PIN_COUNT_WAITER (1 << 5) /* have waiter for sole pin */
|
||||
|
||||
typedef bits16 BufFlags;
|
||||
|
||||
|
@ -54,22 +53,21 @@ typedef struct buftag
|
|||
|
||||
#define CLEAR_BUFFERTAG(a) \
|
||||
( \
|
||||
(a)->rnode.tblNode = InvalidOid, \
|
||||
(a)->rnode.relNode = InvalidOid, \
|
||||
(a)->blockNum = InvalidBlockNumber \
|
||||
(a).rnode.tblNode = InvalidOid, \
|
||||
(a).rnode.relNode = InvalidOid, \
|
||||
(a).blockNum = InvalidBlockNumber \
|
||||
)
|
||||
|
||||
#define INIT_BUFFERTAG(a,xx_reln,xx_blockNum) \
|
||||
( \
|
||||
(a)->blockNum = (xx_blockNum), \
|
||||
(a)->rnode = (xx_reln)->rd_node \
|
||||
(a).rnode = (xx_reln)->rd_node, \
|
||||
(a).blockNum = (xx_blockNum) \
|
||||
)
|
||||
|
||||
#define BUFFERTAGS_EQUAL(a,b) \
|
||||
( \
|
||||
(a)->rnode.tblNode == (b)->rnode.tblNode && \
|
||||
(a)->rnode.relNode == (b)->rnode.relNode && \
|
||||
(a)->blockNum == (b)->blockNum \
|
||||
RelFileNodeEquals((a).rnode, (b).rnode) && \
|
||||
(a).blockNum == (b).blockNum \
|
||||
)
|
||||
|
||||
/*
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/storage/bufmgr.h,v 1.75 2004/02/04 01:24:53 wieck Exp $
|
||||
* $PostgreSQL: pgsql/src/include/storage/bufmgr.h,v 1.76 2004/04/21 18:06:30 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -142,7 +142,7 @@ extern long *LocalRefCount;
|
|||
* prototypes for functions in bufmgr.c
|
||||
*/
|
||||
extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum);
|
||||
extern int ReleaseBuffer(Buffer buffer);
|
||||
extern void ReleaseBuffer(Buffer buffer);
|
||||
extern void WriteBuffer(Buffer buffer);
|
||||
extern void WriteNoReleaseBuffer(Buffer buffer);
|
||||
extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,
|
||||
|
|
Loading…
Reference in New Issue