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:
Tom Lane 2004-04-21 18:06:30 +00:00
parent aeee856564
commit 95a03e9cdf
6 changed files with 331 additions and 431 deletions

View File

@ -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

View File

@ -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;

View File

@ -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]++;
*foundPtr = TRUE;
return &LocalBufferDescriptors[i];
if (bufHdr->flags & BM_VALID)
*foundPtr = TRUE;
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;

View File

@ -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 \
)
/*

View File

@ -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,