Commit 95a03e9c authored by Tom Lane's avatar Tom Lane

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.
parent aeee8565
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -133,11 +133,11 @@ InitBufferPool(void)
buf->bufNext = i + 1; buf->bufNext = i + 1;
CLEAR_BUFFERTAG(&(buf->tag)); CLEAR_BUFFERTAG(buf->tag);
buf->buf_id = i; buf->buf_id = i;
buf->data = MAKE_OFFSET(block); buf->data = MAKE_OFFSET(block);
buf->flags = (BM_DELETED | BM_VALID); buf->flags = 0;
buf->refcount = 0; buf->refcount = 0;
buf->io_in_progress_lock = LWLockAssign(); buf->io_in_progress_lock = LWLockAssign();
buf->cntx_lock = LWLockAssign(); buf->cntx_lock = LWLockAssign();
......
This diff is collapsed.
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -501,7 +501,7 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag,
/* Assert that the buffer remembered in cdb_found is the one */ /* Assert that the buffer remembered in cdb_found is the one */
/* the buffer manager is currently faulting in */ /* 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) if (cdb_replace_index >= 0)
{ {
...@@ -513,7 +513,7 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag, ...@@ -513,7 +513,7 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag,
Assert(cdb_replace->list == STRAT_LIST_T1 || Assert(cdb_replace->list == STRAT_LIST_T1 ||
cdb_replace->list == STRAT_LIST_T2); cdb_replace->list == STRAT_LIST_T2);
Assert(cdb_replace->buf_id == buf->buf_id); 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 * Under normal circumstances we move the evicted T list entry to
...@@ -606,7 +606,7 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag, ...@@ -606,7 +606,7 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag,
Assert(cdb_replace->list == STRAT_LIST_T1 || Assert(cdb_replace->list == STRAT_LIST_T1 ||
cdb_replace->list == STRAT_LIST_T2); cdb_replace->list == STRAT_LIST_T2);
Assert(cdb_replace->buf_id == buf->buf_id); 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) if (cdb_replace->list == STRAT_LIST_T1)
{ {
...@@ -673,7 +673,7 @@ StrategyInvalidateBuffer(BufferDesc *buf) ...@@ -673,7 +673,7 @@ StrategyInvalidateBuffer(BufferDesc *buf)
BufferStrategyCDB *cdb; BufferStrategyCDB *cdb;
/* The buffer cannot be dirty or pinned */ /* 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); Assert(buf->refcount == 0);
/* /*
...@@ -695,16 +695,18 @@ StrategyInvalidateBuffer(BufferDesc *buf) ...@@ -695,16 +695,18 @@ StrategyInvalidateBuffer(BufferDesc *buf)
* Clear out the CDB's buffer tag and association with the buffer * Clear out the CDB's buffer tag and association with the buffer
* and add it to the list of unused CDB's * 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->buf_id = -1;
cdb->next = StrategyControl->listUnusedCDB; cdb->next = StrategyControl->listUnusedCDB;
StrategyControl->listUnusedCDB = cdb_id; StrategyControl->listUnusedCDB = cdb_id;
/* /*
* Clear out the buffer's tag and add it to the list of * 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; buf->bufNext = StrategyControl->listFreeBuffers;
StrategyControl->listFreeBuffers = buf->buf_id; StrategyControl->listFreeBuffers = buf->buf_id;
} }
...@@ -864,7 +866,7 @@ StrategyInitialize(bool init) ...@@ -864,7 +866,7 @@ StrategyInitialize(bool init)
{ {
StrategyCDB[i].next = i + 1; StrategyCDB[i].next = i + 1;
StrategyCDB[i].list = STRAT_LIST_UNUSED; StrategyCDB[i].list = STRAT_LIST_UNUSED;
CLEAR_BUFFERTAG(&(StrategyCDB[i].buf_tag)); CLEAR_BUFFERTAG(StrategyCDB[i].buf_tag);
StrategyCDB[i].buf_id = -1; StrategyCDB[i].buf_id = -1;
} }
StrategyCDB[NBuffers * 2 - 1].next = -1; StrategyCDB[NBuffers * 2 - 1].next = -1;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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; ...@@ -36,19 +36,25 @@ static int nextFreeLocalBuf = 0;
/* /*
* LocalBufferAlloc - * LocalBufferAlloc -
* allocate a local buffer. We do round robin allocation for now. * 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 * BufferDesc *
LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr) LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
{ {
BufferTag newTag; /* identity of requested block */
int i; int i;
BufferDesc *bufHdr = NULL; BufferDesc *bufHdr;
INIT_BUFFERTAG(newTag, reln, blockNum);
/* a low tech search for now -- not optimized for scans */ /* a low tech search for now -- not optimized for scans */
for (i = 0; i < NLocBuffer; i++) for (i = 0; i < NLocBuffer; i++)
{ {
if (LocalBufferDescriptors[i].tag.rnode.relNode == bufHdr = &LocalBufferDescriptors[i];
reln->rd_node.relNode && if (BUFFERTAGS_EQUAL(bufHdr->tag, newTag))
LocalBufferDescriptors[i].tag.blockNum == blockNum)
{ {
#ifdef LBDEBUG #ifdef LBDEBUG
fprintf(stderr, "LB ALLOC (%u,%d) %d\n", fprintf(stderr, "LB ALLOC (%u,%d) %d\n",
...@@ -56,8 +62,14 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr) ...@@ -56,8 +62,14 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
#endif #endif
LocalRefCount[i]++; LocalRefCount[i]++;
*foundPtr = TRUE; if (bufHdr->flags & BM_VALID)
return &LocalBufferDescriptors[i]; *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) ...@@ -67,6 +79,7 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
#endif #endif
/* need to get a new buffer (round robin for now) */ /* need to get a new buffer (round robin for now) */
bufHdr = NULL;
for (i = 0; i < NLocBuffer; i++) for (i = 0; i < NLocBuffer; i++)
{ {
int b = (nextFreeLocalBuf + i) % NLocBuffer; int b = (nextFreeLocalBuf + i) % NLocBuffer;
...@@ -108,7 +121,7 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr) ...@@ -108,7 +121,7 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
* *
* Note this path cannot be taken for a buffer that was previously in * 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 * 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) if (bufHdr->data == (SHMEM_OFFSET) 0)
{ {
...@@ -135,9 +148,8 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr) ...@@ -135,9 +148,8 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
/* /*
* it's all ours now. * it's all ours now.
*/ */
bufHdr->tag.rnode = reln->rd_node; bufHdr->tag = newTag;
bufHdr->tag.blockNum = blockNum; bufHdr->flags &= ~(BM_VALID | BM_DIRTY | BM_JUST_DIRTIED | BM_IO_ERROR);
bufHdr->flags &= ~BM_DIRTY;
bufHdr->cntxDirty = false; bufHdr->cntxDirty = false;
*foundPtr = FALSE; *foundPtr = FALSE;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 @@ ...@@ -24,13 +24,12 @@
/* /*
* Flags for buffer descriptors * Flags for buffer descriptors
*/ */
#define BM_DIRTY (1 << 0) #define BM_DIRTY (1 << 0) /* data needs writing */
#define BM_VALID (1 << 1) #define BM_VALID (1 << 1) /* data is valid */
#define BM_DELETED (1 << 2) #define BM_IO_IN_PROGRESS (1 << 2) /* read or write in progress */
#define BM_IO_IN_PROGRESS (1 << 3) #define BM_IO_ERROR (1 << 3) /* previous I/O failed */
#define BM_IO_ERROR (1 << 4) #define BM_JUST_DIRTIED (1 << 4) /* dirtied since write started */
#define BM_JUST_DIRTIED (1 << 5) #define BM_PIN_COUNT_WAITER (1 << 5) /* have waiter for sole pin */
#define BM_PIN_COUNT_WAITER (1 << 6)
typedef bits16 BufFlags; typedef bits16 BufFlags;
...@@ -54,22 +53,21 @@ typedef struct buftag ...@@ -54,22 +53,21 @@ typedef struct buftag
#define CLEAR_BUFFERTAG(a) \ #define CLEAR_BUFFERTAG(a) \
( \ ( \
(a)->rnode.tblNode = InvalidOid, \ (a).rnode.tblNode = InvalidOid, \
(a)->rnode.relNode = InvalidOid, \ (a).rnode.relNode = InvalidOid, \
(a)->blockNum = InvalidBlockNumber \ (a).blockNum = InvalidBlockNumber \
) )
#define INIT_BUFFERTAG(a,xx_reln,xx_blockNum) \ #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) \ #define BUFFERTAGS_EQUAL(a,b) \
( \ ( \
(a)->rnode.tblNode == (b)->rnode.tblNode && \ RelFileNodeEquals((a).rnode, (b).rnode) && \
(a)->rnode.relNode == (b)->rnode.relNode && \ (a).blockNum == (b).blockNum \
(a)->blockNum == (b)->blockNum \
) )
/* /*
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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; ...@@ -142,7 +142,7 @@ extern long *LocalRefCount;
* prototypes for functions in bufmgr.c * prototypes for functions in bufmgr.c
*/ */
extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum); extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum);
extern int ReleaseBuffer(Buffer buffer); extern void ReleaseBuffer(Buffer buffer);
extern void WriteBuffer(Buffer buffer); extern void WriteBuffer(Buffer buffer);
extern void WriteNoReleaseBuffer(Buffer buffer); extern void WriteNoReleaseBuffer(Buffer buffer);
extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation, extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,
......
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