summaryrefslogtreecommitdiff
path: root/src/backend/storage/buffer/freelist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/storage/buffer/freelist.c')
-rw-r--r--src/backend/storage/buffer/freelist.c196
1 files changed, 100 insertions, 96 deletions
diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 9e956c8d1d..f562d12cce 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -12,7 +12,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.46 2004/08/29 04:12:47 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.47 2004/08/29 05:06:47 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,15 +26,15 @@
/* GUC variable: time in seconds between statistics reports */
-int DebugSharedBuffers = 0;
+int DebugSharedBuffers = 0;
/* Pointers to shared state */
-static BufferStrategyControl *StrategyControl = NULL;
-static BufferStrategyCDB *StrategyCDB = NULL;
+static BufferStrategyControl *StrategyControl = NULL;
+static BufferStrategyCDB *StrategyCDB = NULL;
/* Backend-local state about whether currently vacuuming */
-static bool strategy_hint_vacuum = false;
-static TransactionId strategy_vacuum_xid;
+static bool strategy_hint_vacuum = false;
+static TransactionId strategy_vacuum_xid;
#define T1_TARGET (StrategyControl->target_T1_size)
@@ -47,7 +47,7 @@ static TransactionId strategy_vacuum_xid;
/*
* Macro to remove a CDB from whichever list it currently is on
*/
-#define STRAT_LIST_REMOVE(cdb) \
+#define STRAT_LIST_REMOVE(cdb) \
do { \
Assert((cdb)->list >= 0 && (cdb)->list < STRAT_NUM_LISTS); \
if ((cdb)->prev < 0) \
@@ -71,7 +71,7 @@ do { \
if (StrategyControl->listTail[(l)] < 0) \
{ \
(cdb)->prev = (cdb)->next = -1; \
- StrategyControl->listHead[(l)] = \
+ StrategyControl->listHead[(l)] = \
StrategyControl->listTail[(l)] = \
((cdb) - StrategyCDB); \
} \
@@ -79,9 +79,9 @@ do { \
{ \
(cdb)->next = -1; \
(cdb)->prev = StrategyControl->listTail[(l)]; \
- StrategyCDB[StrategyControl->listTail[(l)]].next = \
+ StrategyCDB[StrategyControl->listTail[(l)]].next = \
((cdb) - StrategyCDB); \
- StrategyControl->listTail[(l)] = \
+ StrategyControl->listTail[(l)] = \
((cdb) - StrategyCDB); \
} \
StrategyControl->listSize[(l)]++; \
@@ -97,7 +97,7 @@ do { \
if (StrategyControl->listHead[(l)] < 0) \
{ \
(cdb)->prev = (cdb)->next = -1; \
- StrategyControl->listHead[(l)] = \
+ StrategyControl->listHead[(l)] = \
StrategyControl->listTail[(l)] = \
((cdb) - StrategyCDB); \
} \
@@ -105,9 +105,9 @@ do { \
{ \
(cdb)->prev = -1; \
(cdb)->next = StrategyControl->listHead[(l)]; \
- StrategyCDB[StrategyControl->listHead[(l)]].prev = \
+ StrategyCDB[StrategyControl->listHead[(l)]].prev = \
((cdb) - StrategyCDB); \
- StrategyControl->listHead[(l)] = \
+ StrategyControl->listHead[(l)] = \
((cdb) - StrategyCDB); \
} \
StrategyControl->listSize[(l)]++; \
@@ -125,9 +125,15 @@ StrategyStatsDump(void)
if (StrategyControl->stat_report + DebugSharedBuffers < now)
{
- long all_hit, b1_hit, t1_hit, t2_hit, b2_hit;
- int id, t1_clean, t2_clean;
- ErrorContextCallback *errcxtold;
+ long all_hit,
+ b1_hit,
+ t1_hit,
+ t2_hit,
+ b2_hit;
+ int id,
+ t1_clean,
+ t2_clean;
+ ErrorContextCallback *errcxtold;
id = StrategyControl->listHead[STRAT_LIST_T1];
t1_clean = 0;
@@ -149,9 +155,7 @@ StrategyStatsDump(void)
}
if (StrategyControl->num_lookup == 0)
- {
all_hit = b1_hit = t1_hit = t2_hit = b2_hit = 0;
- }
else
{
b1_hit = (StrategyControl->num_hit[STRAT_LIST_B1] * 100 /
@@ -202,7 +206,7 @@ BufferDesc *
StrategyBufferLookup(BufferTag *tagPtr, bool recheck,
int *cdb_found_index)
{
- BufferStrategyCDB *cdb;
+ BufferStrategyCDB *cdb;
/* Optional stats printout */
if (DebugSharedBuffers > 0)
@@ -235,8 +239,8 @@ StrategyBufferLookup(BufferTag *tagPtr, bool recheck,
StrategyControl->num_hit[cdb->list]++;
/*
- * If this is a T2 hit, we simply move the CDB to the
- * T2 MRU position and return the found buffer.
+ * If this is a T2 hit, we simply move the CDB to the T2 MRU position
+ * and return the found buffer.
*
* A CDB in T2 cannot have t1_vacuum set, so we needn't check. However,
* if the current process is VACUUM then it doesn't promote to MRU.
@@ -253,12 +257,12 @@ StrategyBufferLookup(BufferTag *tagPtr, bool recheck,
}
/*
- * If this is a T1 hit, we move the buffer to the T2 MRU only if another
- * transaction had read it into T1, *and* neither transaction is a VACUUM.
- * This is required because any UPDATE or DELETE in PostgreSQL does
- * multiple ReadBuffer(), first during the scan, later during the
- * heap_update() or heap_delete(). Otherwise move to T1 MRU. VACUUM
- * doesn't even get to make that happen.
+ * If this is a T1 hit, we move the buffer to the T2 MRU only if
+ * another transaction had read it into T1, *and* neither transaction
+ * is a VACUUM. This is required because any UPDATE or DELETE in
+ * PostgreSQL does multiple ReadBuffer(), first during the scan, later
+ * during the heap_update() or heap_delete(). Otherwise move to T1
+ * MRU. VACUUM doesn't even get to make that happen.
*/
if (cdb->list == STRAT_LIST_T1)
{
@@ -274,10 +278,11 @@ StrategyBufferLookup(BufferTag *tagPtr, bool recheck,
{
STRAT_LIST_REMOVE(cdb);
STRAT_MRU_INSERT(cdb, STRAT_LIST_T1);
+
/*
- * If a non-VACUUM process references a page recently loaded
- * by VACUUM, clear the stigma; the state will now be the
- * same as if this process loaded it originally.
+ * If a non-VACUUM process references a page recently
+ * loaded by VACUUM, clear the stigma; the state will now
+ * be the same as if this process loaded it originally.
*/
if (cdb->t1_vacuum)
{
@@ -297,9 +302,9 @@ StrategyBufferLookup(BufferTag *tagPtr, bool recheck,
* adjust the T1target.
*
* Now for this really to end up as a B1 or B2 cache hit, we must have
- * been flushing for quite some time as the block not only must have been
- * read, but also traveled through the queue and evicted from the T cache
- * again already.
+ * been flushing for quite some time as the block not only must have
+ * been read, but also traveled through the queue and evicted from the
+ * T cache again already.
*
* VACUUM re-reads shouldn't adjust the target either.
*/
@@ -307,26 +312,26 @@ StrategyBufferLookup(BufferTag *tagPtr, bool recheck,
return NULL;
/*
- * Adjust the target size of the T1 cache depending on if this is
- * a B1 or B2 hit.
+ * Adjust the target size of the T1 cache depending on if this is a B1
+ * or B2 hit.
*/
switch (cdb->list)
{
case STRAT_LIST_B1:
+
/*
- * B1 hit means that the T1 cache is probably too
- * small. Adjust the T1 target size and continue
- * below.
+ * B1 hit means that the T1 cache is probably too small.
+ * Adjust the T1 target size and continue below.
*/
T1_TARGET = Min(T1_TARGET + Max(B2_LENGTH / B1_LENGTH, 1),
NBuffers);
break;
case STRAT_LIST_B2:
- /*
- * B2 hit means that the T2 cache is probably too
- * small. Adjust the T1 target size and continue
- * below.
+
+ /*
+ * B2 hit means that the T2 cache is probably too small.
+ * Adjust the T1 target size and continue below.
*/
T1_TARGET = Max(T1_TARGET - Max(B1_LENGTH / B2_LENGTH, 1), 0);
break;
@@ -337,8 +342,8 @@ StrategyBufferLookup(BufferTag *tagPtr, bool recheck,
}
/*
- * Even though we had seen the block in the past, its data is
- * not currently in memory ... cache miss to the bufmgr.
+ * Even though we had seen the block in the past, its data is not
+ * currently in memory ... cache miss to the bufmgr.
*/
return NULL;
}
@@ -349,7 +354,7 @@ StrategyBufferLookup(BufferTag *tagPtr, bool recheck,
*
* Called by the bufmgr to get the next candidate buffer to use in
* BufferAlloc(). The only hard requirement BufferAlloc() has is that
- * this buffer must not currently be pinned.
+ * this buffer must not currently be pinned.
*
* *cdb_replace_index is set to the index of the candidate CDB, or -1 if
* none (meaning we are using a previously free buffer). This is not
@@ -359,8 +364,8 @@ StrategyBufferLookup(BufferTag *tagPtr, bool recheck,
BufferDesc *
StrategyGetBuffer(int *cdb_replace_index)
{
- int cdb_id;
- BufferDesc *buf;
+ int cdb_id;
+ BufferDesc *buf;
if (StrategyControl->listFreeBuffers < 0)
{
@@ -452,12 +457,12 @@ StrategyGetBuffer(int *cdb_replace_index)
/* There is a completely free buffer available - take it */
/*
- * Note: This code uses the side effect that a free buffer
- * can never be pinned or dirty and therefore the call to
+ * Note: This code uses the side effect that a free buffer can
+ * never be pinned or dirty and therefore the call to
* StrategyReplaceBuffer() will happen without the bufmgr
- * releasing the bufmgr-lock in the meantime. That means,
- * that there will never be any reason to recheck. Otherwise
- * we would leak shared buffers here!
+ * releasing the bufmgr-lock in the meantime. That means, that
+ * there will never be any reason to recheck. Otherwise we would
+ * leak shared buffers here!
*/
*cdb_replace_index = -1;
buf = &BufferDescriptors[StrategyControl->listFreeBuffers];
@@ -493,8 +498,8 @@ void
StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag,
int cdb_found_index, int cdb_replace_index)
{
- BufferStrategyCDB *cdb_found;
- BufferStrategyCDB *cdb_replace;
+ BufferStrategyCDB *cdb_found;
+ BufferStrategyCDB *cdb_replace;
if (cdb_found_index >= 0)
{
@@ -504,7 +509,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));
-
+
if (cdb_replace_index >= 0)
{
/* We are satisfying it with an evicted T buffer */
@@ -512,17 +517,18 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag,
/* Assert that the buffer remembered in cdb_replace is */
/* the one the buffer manager has just evicted */
- Assert(cdb_replace->list == STRAT_LIST_T1 ||
+ 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));
/*
- * Under normal circumstances we move the evicted T list entry to
- * the corresponding B list. However, T1 entries that exist only
- * because of VACUUM are just thrown into the unused list instead.
- * We don't expect them to be touched again by the VACUUM, and if
- * we put them into B1 then VACUUM would skew T1_target adjusting.
+ * Under normal circumstances we move the evicted T list entry
+ * to the corresponding B list. However, T1 entries that
+ * exist only because of VACUUM are just thrown into the
+ * unused list instead. We don't expect them to be touched
+ * again by the VACUUM, and if we put them into B1 then VACUUM
+ * would skew T1_target adjusting.
*/
if (cdb_replace->t1_vacuum)
{
@@ -560,8 +566,8 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag,
else
{
/*
- * This was a complete cache miss, so we need to create
- * a new CDB. The goal is to keep T1len+B1len <= c.
+ * This was a complete cache miss, so we need to create a new CDB.
+ * The goal is to keep T1len+B1len <= c.
*/
if (B1_LENGTH > 0 && (T1_LENGTH + B1_LENGTH) >= NBuffers)
{
@@ -600,12 +606,12 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag,
if (cdb_replace_index >= 0)
{
/*
- * The buffer was formerly in a T list, move its CDB
- * to the corresponding B list
+ * The buffer was formerly in a T list, move its CDB to the
+ * corresponding B list
*/
cdb_replace = &StrategyCDB[cdb_replace_index];
- Assert(cdb_replace->list == STRAT_LIST_T1 ||
+ 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));
@@ -651,9 +657,9 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag,
STRAT_MRU_INSERT(cdb_found, STRAT_LIST_T1);
/*
- * Remember the Xid when this buffer went onto T1 to avoid
- * a single UPDATE promoting a newcomer straight into T2.
- * Also remember if it was loaded for VACUUM.
+ * Remember the Xid when this buffer went onto T1 to avoid a
+ * single UPDATE promoting a newcomer straight into T2. Also
+ * remember if it was loaded for VACUUM.
*/
cdb_found->t1_xid = GetCurrentTransactionId();
cdb_found->t1_vacuum = strategy_hint_vacuum;
@@ -671,8 +677,8 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag,
void
StrategyInvalidateBuffer(BufferDesc *buf)
{
- int cdb_id;
- BufferStrategyCDB *cdb;
+ int cdb_id;
+ BufferStrategyCDB *cdb;
/* The buffer cannot be dirty or pinned */
Assert(!(buf->flags & BM_DIRTY) || !(buf->flags & BM_VALID));
@@ -687,15 +693,15 @@ StrategyInvalidateBuffer(BufferDesc *buf)
cdb = &StrategyCDB[cdb_id];
/*
- * Remove the CDB from the hashtable and the ARC queue it is
- * currently on.
+ * Remove the CDB from the hashtable and the ARC queue it is currently
+ * on.
*/
BufTableDelete(&(cdb->buf_tag));
STRAT_LIST_REMOVE(cdb);
/*
- * Clear out the CDB's buffer tag and association with the buffer
- * and add it to the list of unused CDB's
+ * 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);
cdb->buf_id = -1;
@@ -703,9 +709,9 @@ StrategyInvalidateBuffer(BufferDesc *buf)
StrategyControl->listUnusedCDB = cdb_id;
/*
- * Clear out the buffer's tag and add it to the list of
- * currently unused buffers. We must do this to ensure that linear
- * scans of the buffer array don't think the buffer is valid.
+ * Clear out the buffer's tag and add it to the list of 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);
buf->flags &= ~(BM_VALID | BM_DIRTY);
@@ -743,17 +749,17 @@ int
StrategyDirtyBufferList(BufferDesc **buffers, BufferTag *buftags,
int max_buffers)
{
- int num_buffer_dirty = 0;
- int cdb_id_t1;
- int cdb_id_t2;
- int buf_id;
- BufferDesc *buf;
+ int num_buffer_dirty = 0;
+ int cdb_id_t1;
+ int cdb_id_t2;
+ int buf_id;
+ BufferDesc *buf;
/*
- * Traverse the T1 and T2 list LRU to MRU in "parallel"
- * and add all dirty buffers found in that order to the list.
- * The ARC strategy keeps all used buffers including pinned ones
- * in the T1 or T2 list. So we cannot miss any dirty buffers.
+ * Traverse the T1 and T2 list LRU to MRU in "parallel" and add all
+ * dirty buffers found in that order to the list. The ARC strategy
+ * keeps all used buffers including pinned ones in the T1 or T2 list.
+ * So we cannot miss any dirty buffers.
*/
cdb_id_t1 = StrategyControl->listHead[STRAT_LIST_T1];
cdb_id_t2 = StrategyControl->listHead[STRAT_LIST_T2];
@@ -815,8 +821,8 @@ StrategyDirtyBufferList(BufferDesc **buffers, BufferTag *buftags,
void
StrategyInitialize(bool init)
{
- bool found;
- int i;
+ bool found;
+ int i;
/*
* Initialize the shared CDB lookup hashtable
@@ -841,14 +847,14 @@ StrategyInitialize(bool init)
Assert(init);
/*
- * Grab the whole linked list of free buffers for our strategy.
- * We assume it was previously set up by InitBufferPool().
+ * Grab the whole linked list of free buffers for our strategy. We
+ * assume it was previously set up by InitBufferPool().
*/
StrategyControl->listFreeBuffers = 0;
/*
- * We start off with a target T1 list size of
- * half the available cache blocks.
+ * We start off with a target T1 list size of half the available
+ * cache blocks.
*/
StrategyControl->target_T1_size = NBuffers / 2;
@@ -862,7 +868,7 @@ StrategyInitialize(bool init)
StrategyControl->listSize[i] = 0;
StrategyControl->num_hit[i] = 0;
}
- StrategyControl->num_lookup = 0;
+ StrategyControl->num_lookup = 0;
StrategyControl->stat_report = 0;
/*
@@ -879,7 +885,5 @@ StrategyInitialize(bool init)
StrategyControl->listUnusedCDB = 0;
}
else
- {
Assert(!init);
- }
}