]> granicus.if.org Git - postgresql/commitdiff
Ensure that all details of the ARC algorithm are hidden within freelist.c.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 3 Feb 2005 23:29:19 +0000 (23:29 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 3 Feb 2005 23:29:19 +0000 (23:29 +0000)
This refactoring does not change any algorithms or data structures, just
remove visibility of the ARC datastructures from other source files.

src/backend/storage/buffer/buf_init.c
src/backend/storage/buffer/buf_table.c
src/backend/storage/buffer/freelist.c
src/include/storage/buf_internals.h

index 6b6a8289ad83f5dcccc012ecb9bbe13ac87c0a59..f6500fec89e7bdf74c7880a8eeafa1197b654d13 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.70 2004/12/31 22:00:49 pgsql Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.71 2005/02/03 23:29:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -73,7 +73,6 @@ long int      LocalBufferFlushCount;
  *             aborts, it should only unpin the buffers exactly the number of times it
  *             has pinned them, so that it will not blow away buffers of another
  *             backend.
- *
  */
 
 
@@ -120,14 +119,17 @@ InitBufferPool(void)
                block = BufferBlocks;
 
                /*
-                * link the buffers into a single linked list. This will become
-                * the LIFO list of unused buffers returned by
-                * StrategyGetBuffer().
+                * Initialize all the buffer headers.
                 */
                for (i = 0; i < NBuffers; block += BLCKSZ, buf++, i++)
                {
                        Assert(ShmemIsValid((unsigned long) block));
 
+                       /*
+                        * The bufNext fields link together all totally-unused buffers.
+                        * Subsequent management of this list is done by
+                        * StrategyGetBuffer().
+                        */
                        buf->bufNext = i + 1;
 
                        CLEAR_BUFFERTAG(buf->tag);
@@ -142,7 +144,7 @@ InitBufferPool(void)
                        buf->wait_backend_id = 0;
                }
 
-               /* Correct last entry */
+               /* Correct last entry of linked list */
                BufferDescriptors[NBuffers - 1].bufNext = -1;
 
                LWLockRelease(BufMgrLock);
@@ -178,7 +180,8 @@ InitBufferPoolAccess(void)
 
        /*
         * Convert shmem offsets into addresses as seen by this process. This
-        * is just to speed up the BufferGetBlock() macro.
+        * is just to speed up the BufferGetBlock() macro.  It is OK to do this
+        * without any lock since the data pointers never change.
         */
        for (i = 0; i < NBuffers; i++)
                BufferBlockPointers[i] = (Block) MAKE_PTR(BufferDescriptors[i].data);
@@ -201,14 +204,8 @@ BufferShmemSize(void)
        /* size of data pages */
        size += NBuffers * MAXALIGN(BLCKSZ);
 
-       /* size of buffer hash table */
-       size += hash_estimate_size(NBuffers * 2, sizeof(BufferLookupEnt));
-
-       /* size of the shared replacement strategy control block */
-       size += MAXALIGN(sizeof(BufferStrategyControl));
-
-       /* size of the ARC directory blocks */
-       size += MAXALIGN(NBuffers * 2 * sizeof(BufferStrategyCDB));
+       /* size of stuff controlled by freelist.c */
+       size += StrategyShmemSize();
 
        return size;
 }
index 12ac6aba8867ed3a5972ba0309cbb29d88454229..ef79ae9c39390f61726a98466f4e9acce0c4189b 100644 (file)
@@ -1,11 +1,11 @@
 /*-------------------------------------------------------------------------
  *
  * buf_table.c
- *       routines for finding buffers in the buffer pool.
+ *       routines for mapping BufferTags to buffer indexes.
  *
- * NOTE: these days, what this table actually provides is a mapping from
- * BufferTags to CDB indexes, not directly to buffers. The function names
- * are thus slight misnomers.
+ * NOTE: this module is called only by freelist.c, and the "buffer IDs"
+ * it deals with are whatever freelist.c needs them to be; they may not be
+ * directly equivalent to Buffer numbers.
  *
  * Note: all routines in this file assume that the BufMgrLock is held
  * by the caller, so no synchronization is needed.
@@ -16,7 +16,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/buffer/buf_table.c,v 1.38 2004/12/31 22:00:49 pgsql Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/buffer/buf_table.c,v 1.39 2005/02/03 23:29:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "storage/bufmgr.h"
 
 
+/* entry for buffer lookup hashtable */
+typedef struct
+{
+       BufferTag       key;                    /* Tag of a disk page */
+       int                     id;                             /* Associated buffer ID */
+} BufferLookupEnt;
+
 static HTAB *SharedBufHash;
 
 
+/*
+ * Estimate space needed for mapping hashtable
+ *             size is the desired hash table size (possibly more than NBuffers)
+ */
+int
+BufTableShmemSize(int size)
+{
+       return hash_estimate_size(size, sizeof(BufferLookupEnt));
+}
+
 /*
  * Initialize shmem hash table for mapping buffers
- *             size is the desired hash table size (2*NBuffers for ARC algorithm)
+ *             size is the desired hash table size (possibly more than NBuffers)
  */
 void
 InitBufTable(int size)
@@ -56,7 +73,7 @@ InitBufTable(int size)
 
 /*
  * BufTableLookup
- *             Lookup the given BufferTag; return CDB index, or -1 if not found
+ *             Lookup the given BufferTag; return buffer ID, or -1 if not found
  */
 int
 BufTableLookup(BufferTag *tagPtr)
@@ -76,10 +93,10 @@ BufTableLookup(BufferTag *tagPtr)
 
 /*
  * BufTableInsert
- *             Insert a hashtable entry for given tag and CDB index
+ *             Insert a hashtable entry for given tag and buffer ID
  */
 void
-BufTableInsert(BufferTag *tagPtr, int cdb_id)
+BufTableInsert(BufferTag *tagPtr, int buf_id)
 {
        BufferLookupEnt *result;
        bool            found;
@@ -92,15 +109,15 @@ BufTableInsert(BufferTag *tagPtr, int cdb_id)
                                (errcode(ERRCODE_OUT_OF_MEMORY),
                                 errmsg("out of shared memory")));
 
-       if (found)                                      /* found something else in the table? */
+       if (found)                                      /* found something already in the table? */
                elog(ERROR, "shared buffer hash table corrupted");
 
-       result->id = cdb_id;
+       result->id = buf_id;
 }
 
 /*
  * BufTableDelete
- *             Delete the hashtable entry for given tag
+ *             Delete the hashtable entry for given tag (which must exist)
  */
 void
 BufTableDelete(BufferTag *tagPtr)
index eb38fcf21af68fc91a09581c6624a6e7e3a033e5..b960208f74ec03661de5ce1606472f269881fba1 100644 (file)
@@ -3,6 +3,11 @@
  * freelist.c
  *       routines for manipulating the buffer pool's replacement strategy.
  *
+ * The name "freelist.c" is now a bit of a misnomer, since this module
+ * controls not only the list of free buffers per se, but the entire
+ * mechanism for looking up existing shared buffers and the strategy
+ * for choosing replacement victims when needed.
+ *
  * Note: all routines in this file assume that the BufMgrLock is held
  * by the caller, so no synchronization is needed.
  *
@@ -12,7 +17,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.49 2004/12/31 22:00:49 pgsql Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.50 2005/02/03 23:29:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "storage/bufmgr.h"
 
 
+/*
+ * Definitions for the buffer replacement strategy
+ */
+#define STRAT_LIST_UNUSED      (-1)
+#define STRAT_LIST_B1          0
+#define STRAT_LIST_T1          1
+#define STRAT_LIST_T2          2
+#define STRAT_LIST_B2          3
+#define STRAT_NUM_LISTS                4
+
+/*
+ * The Cache Directory Block (CDB) of the Adaptive Replacement Cache (ARC)
+ */
+typedef struct
+{
+       int                     prev;                   /* list links */
+       int                     next;
+       short           list;                   /* ID of list it is currently in */
+       bool            t1_vacuum;              /* t => present only because of VACUUM */
+       TransactionId t1_xid;           /* the xid this entry went onto T1 */
+       BufferTag       buf_tag;                /* page identifier */
+       int                     buf_id;                 /* currently assigned data buffer, or -1 */
+} BufferStrategyCDB;
+
+/*
+ * The shared ARC control information.
+ */
+typedef struct
+{
+       int                     target_T1_size; /* What T1 size are we aiming for */
+       int                     listUnusedCDB;  /* All unused StrategyCDB */
+       int                     listHead[STRAT_NUM_LISTS];              /* ARC lists B1, T1, T2
+                                                                                                * and B2 */
+       int                     listTail[STRAT_NUM_LISTS];
+       int                     listSize[STRAT_NUM_LISTS];
+       Buffer          listFreeBuffers;        /* List of unused buffers */
+
+       long            num_lookup;             /* Some hit statistics */
+       long            num_hit[STRAT_NUM_LISTS];
+       time_t          stat_report;
+
+       /* Array of CDB's starts here */
+       BufferStrategyCDB cdb[1];       /* VARIABLE SIZE ARRAY */
+} BufferStrategyControl;
+
 /* GUC variable: time in seconds between statistics reports */
 int                    DebugSharedBuffers = 0;
 
@@ -812,6 +862,28 @@ StrategyDirtyBufferList(BufferDesc **buffers, BufferTag *buftags,
 }
 
 
+/*
+ * StrategyShmemSize
+ *
+ * estimate the size of shared memory used by the freelist-related structures.
+ */
+int
+StrategyShmemSize(void)
+{
+       int                     size = 0;
+
+       /* size of CDB lookup hash table */
+       size += BufTableShmemSize(NBuffers * 2);
+
+       /* size of the shared replacement strategy control block */
+       size += MAXALIGN(sizeof(BufferStrategyControl));
+
+       /* size of the ARC directory blocks */
+       size += MAXALIGN(NBuffers * 2 * sizeof(BufferStrategyCDB));
+
+       return size;
+}
+
 /*
  * StrategyInitialize -- initialize the buffer cache replacement
  *             strategy.
index a89999f38f46bb73b063172c88db50378e7d75f6..2eee1415da60f2176834f52b8889a9ab64be7c62 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.75 2004/12/31 22:03:42 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.76 2005/02/03 23:29:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -17,8 +17,9 @@
 
 #include "storage/backendid.h"
 #include "storage/buf.h"
-#include "storage/lmgr.h"
 #include "storage/lwlock.h"
+#include "storage/shmem.h"
+#include "utils/rel.h"
 
 
 /*
@@ -40,10 +41,10 @@ typedef bits16 BufFlags;
  * Buffer tag identifies which disk block the buffer contains.
  *
  * Note: the BufferTag data must be sufficient to determine where to write the
- * block, even during a "blind write" with no relcache entry.  It's possible
- * that the backend flushing the buffer doesn't even believe the relation is
- * visible yet (its xact may have started before the xact that created the
- * rel).  The storage manager must be able to cope anyway.
+ * block, without reference to pg_class or pg_tablespace entries.  It's
+ * possible that the backend flushing the buffer doesn't even believe the
+ * relation is visible yet (its xact may have started before the xact that
+ * created the rel).  The storage manager must be able to cope anyway.
  *
  * Note: if there's any pad bytes in the struct, INIT_BUFFERTAG will have
  * to be fixed to zero them, since this struct is used as a hash key.
@@ -107,58 +108,12 @@ typedef struct sbufdesc
 
 #define BufferDescriptorGetBuffer(bdesc) ((bdesc)->buf_id + 1)
 
-/* entry for buffer lookup hashtable */
-typedef struct
-{
-       BufferTag       key;                    /* Tag of a disk page */
-       int                     id;                             /* CDB id of associated CDB */
-} BufferLookupEnt;
-
-/*
- * Definitions for the buffer replacement strategy
- */
-#define STRAT_LIST_UNUSED      (-1)
-#define STRAT_LIST_B1          0
-#define STRAT_LIST_T1          1
-#define STRAT_LIST_T2          2
-#define STRAT_LIST_B2          3
-#define STRAT_NUM_LISTS                4
-
-/*
- * The Cache Directory Block (CDB) of the Adaptive Replacement Cache (ARC)
- */
-typedef struct
-{
-       int                     prev;                   /* list links */
-       int                     next;
-       short           list;                   /* ID of list it is currently in */
-       bool            t1_vacuum;              /* t => present only because of VACUUM */
-       TransactionId t1_xid;           /* the xid this entry went onto T1 */
-       BufferTag       buf_tag;                /* page identifier */
-       int                     buf_id;                 /* currently assigned data buffer, or -1 */
-} BufferStrategyCDB;
-
-/*
- * The shared ARC control information.
- */
-typedef struct
-{
-       int                     target_T1_size; /* What T1 size are we aiming for */
-       int                     listUnusedCDB;  /* All unused StrategyCDB */
-       int                     listHead[STRAT_NUM_LISTS];              /* ARC lists B1, T1, T2
-                                                                                                * and B2 */
-       int                     listTail[STRAT_NUM_LISTS];
-       int                     listSize[STRAT_NUM_LISTS];
-       Buffer          listFreeBuffers;        /* List of unused buffers */
-
-       long            num_lookup;             /* Some hit statistics */
-       long            num_hit[STRAT_NUM_LISTS];
-       time_t          stat_report;
 
-       /* Array of CDB's starts here */
-       BufferStrategyCDB cdb[1];       /* VARIABLE SIZE ARRAY */
-} BufferStrategyControl;
+/* in bufmgr.c */
+extern BufferDesc *BufferDescriptors;
 
+/* in localbuf.c */
+extern BufferDesc *LocalBufferDescriptors;
 
 /* counters in buf_init.c */
 extern long int ReadBufferCount;
@@ -170,11 +125,9 @@ extern long int LocalBufferFlushCount;
 
 
 /*
- * Bufmgr Interface:
+ * Internal routines: only called by bufmgr
  */
 
-/* Internal routines: only called by bufmgr */
-
 /* freelist.c */
 extern BufferDesc *StrategyBufferLookup(BufferTag *tagPtr, bool recheck,
                                         int *cdb_found_index);
@@ -185,20 +138,17 @@ extern void StrategyInvalidateBuffer(BufferDesc *buf);
 extern void StrategyHintVacuum(bool vacuum_active);
 extern int StrategyDirtyBufferList(BufferDesc **buffers, BufferTag *buftags,
                                                int max_buffers);
+extern int     StrategyShmemSize(void);
 extern void StrategyInitialize(bool init);
 
 /* buf_table.c */
+extern int     BufTableShmemSize(int size);
 extern void InitBufTable(int size);
 extern int     BufTableLookup(BufferTag *tagPtr);
-extern void BufTableInsert(BufferTag *tagPtr, int cdb_id);
+extern void BufTableInsert(BufferTag *tagPtr, int buf_id);
 extern void BufTableDelete(BufferTag *tagPtr);
 
-/* bufmgr.c */
-extern BufferDesc *BufferDescriptors;
-
 /* localbuf.c */
-extern BufferDesc *LocalBufferDescriptors;
-
 extern BufferDesc *LocalBufferAlloc(Relation reln, BlockNumber blockNum,
                                 bool *foundPtr);
 extern void WriteLocalBuffer(Buffer buffer, bool release);