public inbox for [email protected]  
help / color / mirror / Atom feed
From: Matthias van de Meent <[email protected]>
To: Heikki Linnakangas <[email protected]>
Cc: Ashutosh Bapat <[email protected]>
Cc: Robert Haas <[email protected]>
Cc: Andres Freund <[email protected]>
Cc: pgsql-hackers <[email protected]>
Cc: [email protected]
Subject: Re: Better shared data structure management and resizable shared data structures
Date: Sun, 5 Apr 2026 21:58:52 +0200
Message-ID: <CAEze2Wio0oudQatHmCRYzurnmBv2_p_muACP2=VkRwiMuJPiMw@mail.gmail.com> (raw)
In-Reply-To: <[email protected]>
References: <CAExHW5vM1bneLYfg0wGeAa=52UiJ3z4vKd3AJ72X8Fw6k3KKrg@mail.gmail.com>
	<[email protected]>
	<CAExHW5uTNWOSxJDWQAUnS0tZawob2_J3dRAtc67NHNZ98X4_xA@mail.gmail.com>
	<CAExHW5t439y61YD9bc7d5wZWHp6J=M43Qu3eEZOBPguZML7o2A@mail.gmail.com>
	<CAExHW5v5FVZbsO9sLzztMZ11C3hgGStE=HkkV2bQkCyncess4w@mail.gmail.com>
	<[email protected]>
	<CAExHW5tCC0T1ky=Jnq-AvMxa67Adaw7aQ4iQAO=BSdHcbSNBVg@mail.gmail.com>
	<[email protected]>
	<CAExHW5tS7GncN90oJWOSzW_3F1EHL9xwe59L7Req3nUVgmObUw@mail.gmail.com>
	<[email protected]>
	<CAEze2WhMOHVgH2Xeyzx=VEk-Ta_YnQUqT+TdBiv5Lx8ESn2WZA@mail.gmail.com>
	<CAExHW5s6h=c_q2m72Nvyj1ghMEhPkOBkeN5Htn7YR=1BrNN-Sw@mail.gmail.com>
	<[email protected]>
	<CAEze2WjQZff3znd6CtG-OBzYZMMqy5TyQSoAo=QTFT38tDndeQ@mail.gmail.com>
	<[email protected]>
	<CAEze2WjgCROMMXY0+j8FFdm3iFcr7By-+6Mwiz=PgGSEydiW3A@mail.gmail.com>
	<[email protected]>

On Sun, 5 Apr 2026 at 17:07, Heikki Linnakangas <[email protected]> wrote:
>
> On 05/04/2026 02:17, Matthias van de Meent wrote:
> > Is this malformatting caused by pgindent? If so, could you see if
> > there's a better way of defining ShmemRequestHash/Struct that doesn't
> > have this indent as output?
>
> Yeah, that's pgindent. Matter of taste, but I think that looks fine. An
> alternative is to put the closing bracket on the same line with the last
> argument and drop the trailing comma:
>
>      ShmemRequestStruct(.name = "pg_stat_statements",
>                         .size = sizeof(pgssSharedState),
>                         .ptr = (void **) &pgss);
>
> That looks OK to me too.

Then let's keep it as per the v11 patch with ugly closing indents --
hopefully someone will fix pgindent in the future, but that's not the
job of this patch.

> > You could make sure that this isn't an issue by maintaining a flag
> > in lwlock.c that's set when the shmem request is made (and reset on
> > shmem exit), which must be false when RequestNamedLWLockTranche() is
> > called, and if not then it should throw an error.
> I'll change it so that the number of locks calculated in
> LWLockShmemRequest() is stored in a global variable, and
> LWLockShmemInit() has an Assert() to cross-checks with that. That
> catches the bug and seems like a good cross-check in general.

Thanks for fixing this!

> > 0010: Not looked at everything yet, but a few comment:
> >
> >> +++ b/src/include/access/slru.h
> >
> > With the changes in the signatures for most/all SLRU functions from a
> > hidden-by-typedef pointer to a visible pointer type, maybe this could
> > be an opportunity to swap them to `const SlruDesc *ctl` wherever
> > possible? I don't think there are many backend-local changes that
> > happen to SlruDescs once we've properly started the backend. I'm happy
> > to provide an incremental patch if you'd like me to spend cycles on it
> > if you're busy.
>
> Yeah sounds like a good idea.

Attached 2 incremental patches:
0001 constifies the expected function arguments, which I propose to include; and
0002 adds 'type* const struct fields' in SlruShared.

0002 was not requested, but it looked feasible to at least try it out
in this subsystem. It might be interesting, but you're free to drop
it.


Kind regards,

Matthias van de Meent
Databricks (https://www.databricks.com)


Attachments:

  [application/octet-stream] nocfbot.v11-0002-Const-qualify-SlruShared-s-fields-and-i.patch (6.7K, 2-nocfbot.v11-0002-Const-qualify-SlruShared-s-fields-and-i.patch)
  download | inline diff:
From 06aa3c327d7ba21a70d416a1bf7a9bc955f629c6 Mon Sep 17 00:00:00 2001
From: Matthias van de Meent <[email protected]>
Date: Sun, 5 Apr 2026 21:48:23 +0200
Subject: [PATCH vnocfbot.v11 2/2] Const-qualify SlruShared's fields and
 internal pointers

These fields are expected to never update, so by const-qualifying
them we protect against inadvertent modification and we allow the
compiler to apply a few more optimizations it previously may not
have been able to prove.
---
 src/backend/access/transam/slru.c | 82 ++++++++++++++++++++-----------
 src/include/access/slru.h         | 24 ++++-----
 2 files changed, 66 insertions(+), 40 deletions(-)

diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index a1e688dd702..cb2bdb35cf4 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -278,6 +278,15 @@ shmem_slru_init(void *location, ShmemStructOpts *base_options)
 	int			nlsns = options->nlsns;
 	char	   *ptr;
 	Size		offset;
+	char	  **page_buffer;
+	SlruPageStatus *page_status;
+	bool	   *page_dirty;
+	int64	   *page_number;
+	int		   *page_lru_count;
+	LWLockPadded *buffer_locks;
+	LWLockPadded *bank_locks;
+	int		   *bank_cur_lru_count;
+	XLogRecPtr *group_lsn;
 
 	shared = (SlruShared) location;
 	desc->shared = shared;
@@ -300,62 +309,79 @@ shmem_slru_init(void *location, ShmemStructOpts *base_options)
 
 	memset(shared, 0, sizeof(SlruSharedData));
 
-	shared->num_slots = nslots;
-	shared->lsn_groups_per_page = nlsns;
-
-	pg_atomic_init_u64(&shared->latest_page_number, 0);
-
-	shared->slru_stats_idx = pgstat_get_slru_index(desc->options.name);
-
 	ptr = (char *) shared;
 	offset = MAXALIGN(sizeof(SlruSharedData));
-	shared->page_buffer = (char **) (ptr + offset);
+	page_buffer = (char **) (ptr + offset);
 	offset += MAXALIGN(nslots * sizeof(char *));
-	shared->page_status = (SlruPageStatus *) (ptr + offset);
+	page_status = (SlruPageStatus *) (ptr + offset);
 	offset += MAXALIGN(nslots * sizeof(SlruPageStatus));
-	shared->page_dirty = (bool *) (ptr + offset);
+	page_dirty = (bool *) (ptr + offset);
 	offset += MAXALIGN(nslots * sizeof(bool));
-	shared->page_number = (int64 *) (ptr + offset);
+	page_number = (int64 *) (ptr + offset);
 	offset += MAXALIGN(nslots * sizeof(int64));
-	shared->page_lru_count = (int *) (ptr + offset);
+	page_lru_count = (int *) (ptr + offset);
 	offset += MAXALIGN(nslots * sizeof(int));
 
 	/* Initialize LWLocks */
-	shared->buffer_locks = (LWLockPadded *) (ptr + offset);
+	buffer_locks = (LWLockPadded *) (ptr + offset);
 	offset += MAXALIGN(nslots * sizeof(LWLockPadded));
-	shared->bank_locks = (LWLockPadded *) (ptr + offset);
+	bank_locks = (LWLockPadded *) (ptr + offset);
 	offset += MAXALIGN(nbanks * sizeof(LWLockPadded));
-	shared->bank_cur_lru_count = (int *) (ptr + offset);
+	bank_cur_lru_count = (int *) (ptr + offset);
 	offset += MAXALIGN(nbanks * sizeof(int));
 
 	if (nlsns > 0)
 	{
-		shared->group_lsn = (XLogRecPtr *) (ptr + offset);
+		group_lsn = (XLogRecPtr *) (ptr + offset);
 		offset += MAXALIGN(nslots * nlsns * sizeof(XLogRecPtr));
 	}
+	else
+		group_lsn = NULL;
+
+	/* Initialize the slot banks. */
+	for (int bankno = 0; bankno < nbanks; bankno++)
+	{
+		LWLockInitialize(&bank_locks[bankno].lock, desc->options.bank_tranche_id);
+		bank_cur_lru_count[bankno] = 0;
+	}
 
 	ptr += BUFFERALIGN(offset);
 	for (int slotno = 0; slotno < nslots; slotno++)
 	{
-		LWLockInitialize(&shared->buffer_locks[slotno].lock,
+		LWLockInitialize(&buffer_locks[slotno].lock,
 						 desc->options.buffer_tranche_id);
 
-		shared->page_buffer[slotno] = ptr;
-		shared->page_status[slotno] = SLRU_PAGE_EMPTY;
-		shared->page_dirty[slotno] = false;
-		shared->page_lru_count[slotno] = 0;
+		page_buffer[slotno] = ptr;
+		page_status[slotno] = SLRU_PAGE_EMPTY;
+		page_dirty[slotno] = false;
+		page_lru_count[slotno] = 0;
 		ptr += BLCKSZ;
 	}
 
-	/* Initialize the slot banks. */
-	for (int bankno = 0; bankno < nbanks; bankno++)
-	{
-		LWLockInitialize(&shared->bank_locks[bankno].lock, desc->options.bank_tranche_id);
-		shared->bank_cur_lru_count[bankno] = 0;
-	}
-
 	/* Should fit to estimated shmem size */
 	Assert(ptr - (char *) shared <= SimpleLruShmemSize(nslots, nlsns));
+
+
+	{
+		SlruSharedData template = {
+			.num_slots = nslots,
+			.lsn_groups_per_page = nlsns,
+			.page_buffer = page_buffer,
+			.page_status = page_status,
+			.page_dirty = page_dirty,
+			.page_number = page_number,
+			.page_lru_count = page_lru_count,
+			.buffer_locks = buffer_locks,
+			.bank_locks = bank_locks,
+			.bank_cur_lru_count = bank_cur_lru_count,
+			.group_lsn = group_lsn,
+			.slru_stats_idx = pgstat_get_slru_index(desc->options.name),
+		};
+
+		pg_atomic_init_u64(&template.latest_page_number, 0);
+
+		memcpy(shared, &template, sizeof(SlruSharedData));
+	}
 }
 
 void
diff --git a/src/include/access/slru.h b/src/include/access/slru.h
index 74ea84deec5..b6854af3119 100644
--- a/src/include/access/slru.h
+++ b/src/include/access/slru.h
@@ -48,23 +48,23 @@ typedef enum
 typedef struct SlruSharedData
 {
 	/* Number of buffers managed by this SLRU structure */
-	int			num_slots;
+	const int	num_slots;
 
 	/*
 	 * Arrays holding info for each buffer slot.  Page number is undefined
 	 * when status is EMPTY, as is page_lru_count.
 	 */
-	char	  **page_buffer;
-	SlruPageStatus *page_status;
-	bool	   *page_dirty;
-	int64	   *page_number;
-	int		   *page_lru_count;
+	char	   *const *const page_buffer;
+	SlruPageStatus *const page_status;
+	bool	   *const page_dirty;
+	int64	   *const page_number;
+	int		   *const page_lru_count;
 
 	/* The buffer_locks protects the I/O on each buffer slots */
-	LWLockPadded *buffer_locks;
+	LWLockPadded *const buffer_locks;
 
 	/* Locks to protect the in memory buffer slot access in SLRU bank. */
-	LWLockPadded *bank_locks;
+	LWLockPadded *const bank_locks;
 
 	/*----------
 	 * A bank-wise LRU counter is maintained because we do a victim buffer
@@ -81,7 +81,7 @@ typedef struct SlruSharedData
 	 * works as long as no page's age exceeds INT_MAX counts.
 	 *----------
 	 */
-	int		   *bank_cur_lru_count;
+	int		   *const bank_cur_lru_count;
 
 	/*
 	 * Optional array of WAL flush LSNs associated with entries in the SLRU
@@ -91,8 +91,8 @@ typedef struct SlruSharedData
 	 * highest LSN known for a contiguous group of SLRU entries on that slot's
 	 * page.
 	 */
-	XLogRecPtr *group_lsn;
-	int			lsn_groups_per_page;
+	XLogRecPtr *const group_lsn;
+	const int	lsn_groups_per_page;
 
 	/*
 	 * latest_page_number is the page number of the current end of the log;
@@ -102,7 +102,7 @@ typedef struct SlruSharedData
 	pg_atomic_uint64 latest_page_number;
 
 	/* SLRU's index for statistics purposes (might not be unique) */
-	int			slru_stats_idx;
+	const int	slru_stats_idx;
 } SlruSharedData;
 
 typedef SlruSharedData *SlruShared;
-- 
2.50.1 (Apple Git-155)



  [application/octet-stream] nocfbot.v11-0001-Add-const-qualification-in-SLRU-subsyst.patch (15.3K, 3-nocfbot.v11-0001-Add-const-qualification-in-SLRU-subsyst.patch)
  download | inline diff:
From 53f491e2565f42fc1fcb3612fe821b1c3b796d4b Mon Sep 17 00:00:00 2001
From: Matthias van de Meent <[email protected]>
Date: Sun, 5 Apr 2026 21:46:31 +0200
Subject: [PATCH vnocfbot.v11 1/2] Add const qualification in SLRU subsystem

With SlruCtl being replaced with SlruDesc*, we can const-qualify the
input arguments of various SLRU functions without significant effort.
In passing, some other arguments are also const-qualified.
---
 src/backend/access/transam/slru.c      | 78 ++++++++++++++------------
 src/include/access/slru.h              | 38 +++++++------
 src/test/modules/test_slru/test_slru.c |  3 +-
 3 files changed, 63 insertions(+), 56 deletions(-)

diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index 47dd52d6749..a1e688dd702 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -91,7 +91,7 @@
  *  dir/123456 for [2^20, 2^24-1]
  */
 static inline int
-SlruFileName(SlruDesc *ctl, char *path, int64 segno)
+SlruFileName(const SlruDesc *ctl, char *path, int64 segno)
 {
 	if (ctl->options.long_segment_names)
 	{
@@ -178,19 +178,22 @@ static SlruErrorCause slru_errcause;
 static int	slru_errno;
 
 
-static void SimpleLruZeroLSNs(SlruDesc *ctl, int slotno);
-static void SimpleLruWaitIO(SlruDesc *ctl, int slotno);
-static void SlruInternalWritePage(SlruDesc *ctl, int slotno, SlruWriteAll fdata);
-static bool SlruPhysicalReadPage(SlruDesc *ctl, int64 pageno, int slotno);
-static bool SlruPhysicalWritePage(SlruDesc *ctl, int64 pageno, int slotno,
+static void SimpleLruZeroLSNs(const SlruDesc *ctl, int slotno);
+static void SimpleLruWaitIO(const SlruDesc *ctl, int slotno);
+static void SlruInternalWritePage(const SlruDesc *ctl, int slotno,
 								  SlruWriteAll fdata);
-static void SlruReportIOError(SlruDesc *ctl, int64 pageno,
+static bool SlruPhysicalReadPage(const SlruDesc *ctl, int64 pageno,
+								 int slotno);
+static bool SlruPhysicalWritePage(const SlruDesc *ctl, int64 pageno,
+								  int slotno, SlruWriteAll fdata);
+static void SlruReportIOError(const SlruDesc *ctl, int64 pageno,
 							  const void *opaque_data);
-static int	SlruSelectLRUPage(SlruDesc *ctl, int64 pageno);
+static int	SlruSelectLRUPage(const SlruDesc *ctl, int64 pageno);
 
-static bool SlruScanDirCbDeleteCutoff(SlruDesc *ctl, char *filename,
+static bool SlruScanDirCbDeleteCutoff(const SlruDesc *ctl,
+									  const char *filename,
 									  int64 segpage, void *data);
-static void SlruInternalDeleteSegment(SlruDesc *ctl, int64 segno);
+static void SlruInternalDeleteSegment(const SlruDesc *ctl, int64 segno);
 static inline void SlruRecentlyUsed(SlruShared shared, int slotno);
 
 
@@ -394,7 +397,7 @@ check_slru_buffers(const char *name, int *newval)
  * Bank lock must be held at entry, and will be held at exit.
  */
 int
-SimpleLruZeroPage(SlruDesc *ctl, int64 pageno)
+SimpleLruZeroPage(const SlruDesc *ctl, int64 pageno)
 {
 	SlruShared	shared = ctl->shared;
 	int			slotno;
@@ -447,7 +450,7 @@ SimpleLruZeroPage(SlruDesc *ctl, int64 pageno)
  * This assumes that InvalidXLogRecPtr is bitwise-all-0.
  */
 static void
-SimpleLruZeroLSNs(SlruDesc *ctl, int slotno)
+SimpleLruZeroLSNs(const SlruDesc *ctl, int slotno)
 {
 	SlruShared	shared = ctl->shared;
 
@@ -463,7 +466,7 @@ SimpleLruZeroLSNs(SlruDesc *ctl, int slotno)
  * SLRU bank lock is acquired and released here.
  */
 void
-SimpleLruZeroAndWritePage(SlruDesc *ctl, int64 pageno)
+SimpleLruZeroAndWritePage(const SlruDesc *ctl, int64 pageno)
 {
 	int			slotno;
 	LWLock	   *lock;
@@ -489,7 +492,7 @@ SimpleLruZeroAndWritePage(SlruDesc *ctl, int64 pageno)
  * Bank lock must be held at entry, and will be held at exit.
  */
 static void
-SimpleLruWaitIO(SlruDesc *ctl, int slotno)
+SimpleLruWaitIO(const SlruDesc *ctl, int slotno)
 {
 	SlruShared	shared = ctl->shared;
 	int			bankno = SlotGetBankNumber(slotno);
@@ -547,7 +550,7 @@ SimpleLruWaitIO(SlruDesc *ctl, int slotno)
  * The correct bank lock must be held at entry, and will be held at exit.
  */
 int
-SimpleLruReadPage(SlruDesc *ctl, int64 pageno, bool write_ok,
+SimpleLruReadPage(const SlruDesc *ctl, int64 pageno, bool write_ok,
 				  const void *opaque_data)
 {
 	SlruShared	shared = ctl->shared;
@@ -651,7 +654,7 @@ SimpleLruReadPage(SlruDesc *ctl, int64 pageno, bool write_ok,
  * It is unspecified whether the lock will be shared or exclusive.
  */
 int
-SimpleLruReadPage_ReadOnly(SlruDesc *ctl, int64 pageno, const void *opaque_data)
+SimpleLruReadPage_ReadOnly(const SlruDesc *ctl, int64 pageno, const void *opaque_data)
 {
 	SlruShared	shared = ctl->shared;
 	LWLock	   *banklock = SimpleLruGetBankLock(ctl, pageno);
@@ -698,7 +701,7 @@ SimpleLruReadPage_ReadOnly(SlruDesc *ctl, int64 pageno, const void *opaque_data)
  * Bank lock must be held at entry, and will be held at exit.
  */
 static void
-SlruInternalWritePage(SlruDesc *ctl, int slotno, SlruWriteAll fdata)
+SlruInternalWritePage(const SlruDesc *ctl, int slotno, SlruWriteAll fdata)
 {
 	SlruShared	shared = ctl->shared;
 	int64		pageno = shared->page_number[slotno];
@@ -778,7 +781,7 @@ SlruInternalWritePage(SlruDesc *ctl, int slotno, SlruWriteAll fdata)
  * fdata is always passed a NULL here.
  */
 void
-SimpleLruWritePage(SlruDesc *ctl, int slotno)
+SimpleLruWritePage(const SlruDesc *ctl, int slotno)
 {
 	Assert(ctl->shared->page_status[slotno] != SLRU_PAGE_EMPTY);
 
@@ -792,7 +795,7 @@ SimpleLruWritePage(SlruDesc *ctl, int slotno)
  * large enough to contain the given page.
  */
 bool
-SimpleLruDoesPhysicalPageExist(SlruDesc *ctl, int64 pageno)
+SimpleLruDoesPhysicalPageExist(const SlruDesc *ctl, int64 pageno)
 {
 	int64		segno = pageno / SLRU_PAGES_PER_SEGMENT;
 	int			rpageno = pageno % SLRU_PAGES_PER_SEGMENT;
@@ -850,7 +853,7 @@ SimpleLruDoesPhysicalPageExist(SlruDesc *ctl, int64 pageno)
  * read/write operations.  We could cache one virtual file pointer ...
  */
 static bool
-SlruPhysicalReadPage(SlruDesc *ctl, int64 pageno, int slotno)
+SlruPhysicalReadPage(const SlruDesc *ctl, int64 pageno, int slotno)
 {
 	SlruShared	shared = ctl->shared;
 	int64		segno = pageno / SLRU_PAGES_PER_SEGMENT;
@@ -922,7 +925,7 @@ SlruPhysicalReadPage(SlruDesc *ctl, int64 pageno, int slotno)
  * SimpleLruWriteAll.
  */
 static bool
-SlruPhysicalWritePage(SlruDesc *ctl, int64 pageno, int slotno, SlruWriteAll fdata)
+SlruPhysicalWritePage(const SlruDesc *ctl, int64 pageno, int slotno, SlruWriteAll fdata)
 {
 	SlruShared	shared = ctl->shared;
 	int64		segno = pageno / SLRU_PAGES_PER_SEGMENT;
@@ -1094,7 +1097,7 @@ SlruPhysicalWritePage(SlruDesc *ctl, int64 pageno, int slotno, SlruWriteAll fdat
  * SlruPhysicalWritePage.  Call this after cleaning up shared-memory state.
  */
 static void
-SlruReportIOError(SlruDesc *ctl, int64 pageno, const void *opaque_data)
+SlruReportIOError(const SlruDesc *ctl, int64 pageno, const void *opaque_data)
 {
 	int64		segno = pageno / SLRU_PAGES_PER_SEGMENT;
 	int			rpageno = pageno % SLRU_PAGES_PER_SEGMENT;
@@ -1216,7 +1219,7 @@ SlruRecentlyUsed(SlruShared shared, int slotno)
  * The correct bank lock must be held at entry, and will be held at exit.
  */
 static int
-SlruSelectLRUPage(SlruDesc *ctl, int64 pageno)
+SlruSelectLRUPage(const SlruDesc *ctl, int64 pageno)
 {
 	SlruShared	shared = ctl->shared;
 
@@ -1369,7 +1372,7 @@ SlruSelectLRUPage(SlruDesc *ctl, int64 pageno)
  * entries are on disk.
  */
 void
-SimpleLruWriteAll(SlruDesc *ctl, bool allow_redirtied)
+SimpleLruWriteAll(const SlruDesc *ctl, bool allow_redirtied)
 {
 	SlruShared	shared = ctl->shared;
 	SlruWriteAllData fdata;
@@ -1455,7 +1458,7 @@ SimpleLruWriteAll(SlruDesc *ctl, bool allow_redirtied)
  * after it has accrued freshly-written data.
  */
 void
-SimpleLruTruncate(SlruDesc *ctl, int64 cutoffPage)
+SimpleLruTruncate(const SlruDesc *ctl, int64 cutoffPage)
 {
 	SlruShared	shared = ctl->shared;
 	int			prevbank;
@@ -1550,7 +1553,7 @@ restart:
  * they either can't yet contain anything, or have already been cleaned out.
  */
 static void
-SlruInternalDeleteSegment(SlruDesc *ctl, int64 segno)
+SlruInternalDeleteSegment(const SlruDesc *ctl, int64 segno)
 {
 	char		path[MAXPGPATH];
 
@@ -1573,7 +1576,7 @@ SlruInternalDeleteSegment(SlruDesc *ctl, int64 segno)
  * Delete an individual SLRU segment, identified by the segment number.
  */
 void
-SlruDeleteSegment(SlruDesc *ctl, int64 segno)
+SlruDeleteSegment(const SlruDesc *ctl, int64 segno)
 {
 	SlruShared	shared = ctl->shared;
 	int			prevbank = SlotGetBankNumber(0);
@@ -1650,7 +1653,7 @@ restart:
  * first>=cutoff && last>=cutoff: no; every page of this segment is too young
  */
 static bool
-SlruMayDeleteSegment(SlruDesc *ctl, int64 segpage, int64 cutoffPage)
+SlruMayDeleteSegment(const SlruDesc *ctl, int64 segpage, int64 cutoffPage)
 {
 	int64		seg_last_page = segpage + SLRU_PAGES_PER_SEGMENT - 1;
 
@@ -1662,7 +1665,7 @@ SlruMayDeleteSegment(SlruDesc *ctl, int64 segpage, int64 cutoffPage)
 
 #ifdef USE_ASSERT_CHECKING
 static void
-SlruPagePrecedesTestOffset(SlruDesc *ctl, int per_page, uint32 offset)
+SlruPagePrecedesTestOffset(const SlruDesc *ctl, int per_page, uint32 offset)
 {
 	TransactionId lhs,
 				rhs;
@@ -1747,7 +1750,7 @@ SlruPagePrecedesTestOffset(SlruDesc *ctl, int per_page, uint32 offset)
  * do not apply to them.)
  */
 void
-SlruPagePrecedesUnitTests(SlruDesc *ctl, int per_page)
+SlruPagePrecedesUnitTests(const SlruDesc *ctl, int per_page)
 {
 	/* Test first, middle and last entries of a page. */
 	SlruPagePrecedesTestOffset(ctl, per_page, 0);
@@ -1762,8 +1765,8 @@ SlruPagePrecedesUnitTests(SlruDesc *ctl, int per_page)
  *		one containing the page passed as "data".
  */
 bool
-SlruScanDirCbReportPresence(SlruDesc *ctl, char *filename, int64 segpage,
-							void *data)
+SlruScanDirCbReportPresence(const SlruDesc *ctl, const char *filename,
+							int64 segpage, void *data)
 {
 	int64		cutoffPage = *(int64 *) data;
 
@@ -1778,7 +1781,7 @@ SlruScanDirCbReportPresence(SlruDesc *ctl, char *filename, int64 segpage,
  *		This callback deletes segments prior to the one passed in as "data".
  */
 static bool
-SlruScanDirCbDeleteCutoff(SlruDesc *ctl, char *filename, int64 segpage,
+SlruScanDirCbDeleteCutoff(const SlruDesc *ctl, const char *filename, int64 segpage,
 						  void *data)
 {
 	int64		cutoffPage = *(int64 *) data;
@@ -1794,7 +1797,8 @@ SlruScanDirCbDeleteCutoff(SlruDesc *ctl, char *filename, int64 segpage,
  *		This callback deletes all segments.
  */
 bool
-SlruScanDirCbDeleteAll(SlruDesc *ctl, char *filename, int64 segpage, void *data)
+SlruScanDirCbDeleteAll(const SlruDesc *ctl, const char *filename,
+					   int64 segpage, void *data)
 {
 	SlruInternalDeleteSegment(ctl, segpage / SLRU_PAGES_PER_SEGMENT);
 
@@ -1808,7 +1812,7 @@ SlruScanDirCbDeleteAll(SlruDesc *ctl, char *filename, int64 segpage, void *data)
  * SLRU segment.
  */
 static inline bool
-SlruCorrectSegmentFilenameLength(SlruDesc *ctl, size_t len)
+SlruCorrectSegmentFilenameLength(const SlruDesc *ctl, size_t len)
 {
 	if (ctl->options.long_segment_names)
 		return (len == 15);		/* see SlruFileName() */
@@ -1841,7 +1845,7 @@ SlruCorrectSegmentFilenameLength(SlruDesc *ctl, size_t len)
  * Note that no locking is applied.
  */
 bool
-SlruScanDirectory(SlruDesc *ctl, SlruScanCallback callback, void *data)
+SlruScanDirectory(const SlruDesc *ctl, SlruScanCallback callback, void *data)
 {
 	bool		retval = false;
 	DIR		   *cldir;
@@ -1881,7 +1885,7 @@ SlruScanDirectory(SlruDesc *ctl, SlruScanCallback callback, void *data)
  * performs the fsync.
  */
 int
-SlruSyncFileTag(SlruDesc *ctl, const FileTag *ftag, char *path)
+SlruSyncFileTag(const SlruDesc *ctl, const FileTag *ftag, char *path)
 {
 	int			fd;
 	int			save_errno;
diff --git a/src/include/access/slru.h b/src/include/access/slru.h
index 36a7514d7a0..74ea84deec5 100644
--- a/src/include/access/slru.h
+++ b/src/include/access/slru.h
@@ -200,7 +200,7 @@ typedef struct SlruDesc
  * respective bank.
  */
 static inline LWLock *
-SimpleLruGetBankLock(SlruDesc *ctl, int64 pageno)
+SimpleLruGetBankLock(const SlruDesc *ctl, int64 pageno)
 {
 	int			bankno;
 
@@ -215,34 +215,36 @@ extern void SimpleLruRequestWithOpts(const SlruOpts *options);
 	SimpleLruRequestWithOpts(&(SlruOpts){__VA_ARGS__})
 
 extern int	SimpleLruAutotuneBuffers(int divisor, int max);
-extern int	SimpleLruZeroPage(SlruDesc *ctl, int64 pageno);
-extern void SimpleLruZeroAndWritePage(SlruDesc *ctl, int64 pageno);
-extern int	SimpleLruReadPage(SlruDesc *ctl, int64 pageno, bool write_ok,
+extern int	SimpleLruZeroPage(const SlruDesc *ctl, int64 pageno);
+extern void SimpleLruZeroAndWritePage(const SlruDesc *ctl, int64 pageno);
+extern int	SimpleLruReadPage(const SlruDesc *ctl, int64 pageno, bool write_ok,
 							  const void *opaque_data);
-extern int	SimpleLruReadPage_ReadOnly(SlruDesc *ctl, int64 pageno,
+extern int	SimpleLruReadPage_ReadOnly(const SlruDesc *ctl, int64 pageno,
 									   const void *opaque_data);
-extern void SimpleLruWritePage(SlruDesc *ctl, int slotno);
-extern void SimpleLruWriteAll(SlruDesc *ctl, bool allow_redirtied);
+extern void SimpleLruWritePage(const SlruDesc *ctl, int slotno);
+extern void SimpleLruWriteAll(const SlruDesc *ctl, bool allow_redirtied);
 #ifdef USE_ASSERT_CHECKING
-extern void SlruPagePrecedesUnitTests(SlruDesc *ctl, int per_page);
+extern void SlruPagePrecedesUnitTests(const SlruDesc *ctl, int per_page);
 #else
 #define SlruPagePrecedesUnitTests(ctl, per_page) do {} while (0)
 #endif
-extern void SimpleLruTruncate(SlruDesc *ctl, int64 cutoffPage);
-extern bool SimpleLruDoesPhysicalPageExist(SlruDesc *ctl, int64 pageno);
+extern void SimpleLruTruncate(const SlruDesc *ctl, int64 cutoffPage);
+extern bool SimpleLruDoesPhysicalPageExist(const SlruDesc *ctl, int64 pageno);
 
-typedef bool (*SlruScanCallback) (SlruDesc *ctl, char *filename, int64 segpage,
-								  void *data);
-extern bool SlruScanDirectory(SlruDesc *ctl, SlruScanCallback callback, void *data);
-extern void SlruDeleteSegment(SlruDesc *ctl, int64 segno);
+typedef bool (*SlruScanCallback) (const SlruDesc *ctl, const char *filename,
+								  int64 segpage, void *data);
+extern bool SlruScanDirectory(const SlruDesc *ctl, SlruScanCallback callback,
+							  void *data);
+extern void SlruDeleteSegment(const SlruDesc *ctl, int64 segno);
 
-extern int	SlruSyncFileTag(SlruDesc *ctl, const FileTag *ftag, char *path);
+extern int	SlruSyncFileTag(const SlruDesc *ctl, const FileTag *ftag,
+							char *path);
 
 /* SlruScanDirectory public callbacks */
-extern bool SlruScanDirCbReportPresence(SlruDesc *ctl, char *filename,
+extern bool SlruScanDirCbReportPresence(const SlruDesc *ctl, const char *filename,
 										int64 segpage, void *data);
-extern bool SlruScanDirCbDeleteAll(SlruDesc *ctl, char *filename, int64 segpage,
-								   void *data);
+extern bool SlruScanDirCbDeleteAll(const SlruDesc *ctl, const char *filename,
+								   int64 segpage, void *data);
 extern bool check_slru_buffers(const char *name, int *newval);
 
 extern void shmem_slru_init(void *location, ShmemStructOpts *options);
diff --git a/src/test/modules/test_slru/test_slru.c b/src/test/modules/test_slru/test_slru.c
index 40efffdbf62..5dfa082ed25 100644
--- a/src/test/modules/test_slru/test_slru.c
+++ b/src/test/modules/test_slru/test_slru.c
@@ -55,7 +55,8 @@ static const ShmemCallbacks test_slru_shmem_callbacks = {
 #define TestSlruCtl			(&TestSlruDesc)
 
 static bool
-test_slru_scan_cb(SlruDesc *ctl, char *filename, int64 segpage, void *data)
+test_slru_scan_cb(const SlruDesc *ctl, const char *filename, int64 segpage,
+				  void *data)
 {
 	elog(NOTICE, "Calling test_slru_scan_cb()");
 	return SlruScanDirCbDeleteAll(ctl, filename, segpage, data);
-- 
2.50.1 (Apple Git-155)



view thread (82+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]
  Subject: Re: Better shared data structure management and resizable shared data structures
  In-Reply-To: <CAEze2Wio0oudQatHmCRYzurnmBv2_p_muACP2=VkRwiMuJPiMw@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox