aboutsummaryrefslogtreecommitdiff
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.c61
1 files changed, 52 insertions, 9 deletions
diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index f122709fbe2..1c804fd2f59 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -540,8 +540,7 @@ StrategyInitialize(bool init)
BufferAccessStrategy
GetAccessStrategy(BufferAccessStrategyType btype)
{
- BufferAccessStrategy strategy;
- int nbuffers;
+ int ring_size_kb;
/*
* Select ring size to use. See buffer/README for rationales.
@@ -556,13 +555,13 @@ GetAccessStrategy(BufferAccessStrategyType btype)
return NULL;
case BAS_BULKREAD:
- nbuffers = 256 * 1024 / BLCKSZ;
+ ring_size_kb = 256;
break;
case BAS_BULKWRITE:
- nbuffers = 16 * 1024 * 1024 / BLCKSZ;
+ ring_size_kb = 16 * 1024;
break;
case BAS_VACUUM:
- nbuffers = 256 * 1024 / BLCKSZ;
+ ring_size_kb = 256;
break;
default:
@@ -571,22 +570,66 @@ GetAccessStrategy(BufferAccessStrategyType btype)
return NULL; /* keep compiler quiet */
}
- /* Make sure ring isn't an undue fraction of shared buffers */
- nbuffers = Min(NBuffers / 8, nbuffers);
+ return GetAccessStrategyWithSize(btype, ring_size_kb);
+}
+
+/*
+ * GetAccessStrategyWithSize -- create a BufferAccessStrategy object with a
+ * number of buffers equivalent to the passed in size.
+ *
+ * If the given ring size is 0, no BufferAccessStrategy will be created and
+ * the function will return NULL. ring_size_kb must not be negative.
+ */
+BufferAccessStrategy
+GetAccessStrategyWithSize(BufferAccessStrategyType btype, int ring_size_kb)
+{
+ int ring_buffers;
+ BufferAccessStrategy strategy;
+
+ Assert(ring_size_kb >= 0);
+
+ /* Figure out how many buffers ring_size_kb is */
+ ring_buffers = ring_size_kb / (BLCKSZ / 1024);
+
+ /* 0 means unlimited, so no BufferAccessStrategy required */
+ if (ring_buffers == 0)
+ return NULL;
+
+ /* Cap to 1/8th of shared_buffers */
+ ring_buffers = Min(NBuffers / 8, ring_buffers);
+
+ /* NBuffers should never be less than 16, so this shouldn't happen */
+ Assert(ring_buffers > 0);
/* Allocate the object and initialize all elements to zeroes */
strategy = (BufferAccessStrategy)
palloc0(offsetof(BufferAccessStrategyData, buffers) +
- nbuffers * sizeof(Buffer));
+ ring_buffers * sizeof(Buffer));
/* Set fields that don't start out zero */
strategy->btype = btype;
- strategy->nbuffers = nbuffers;
+ strategy->nbuffers = ring_buffers;
return strategy;
}
/*
+ * GetAccessStrategyBufferCount -- an accessor for the number of buffers in
+ * the ring
+ *
+ * Returns 0 on NULL input to match behavior of GetAccessStrategyWithSize()
+ * returning NULL with 0 size.
+ */
+int
+GetAccessStrategyBufferCount(BufferAccessStrategy strategy)
+{
+ if (strategy == NULL)
+ return 0;
+
+ return strategy->nbuffers;
+}
+
+/*
* FreeAccessStrategy -- release a BufferAccessStrategy object
*
* A simple pfree would do at the moment, but we would prefer that callers