From 2aab14a052de2d09ee7171cfffe94aa88175c72d Mon Sep 17 00:00:00 2001
From: Aleksander Alekseev <aleksander@timescale.com>
Date: Wed, 2 Nov 2022 11:26:23 +0300
Subject: [PATCH v1] Constify the arguments of ilist.c/h functions

Const qualifiers ensure that we don't do something stupid in the function
implementation. Additionally they clarify the interface. As an example:

void
slist_delete(slist_head *head, const slist_node *node)

Here one can instantly tell that node->next is not going to be set to NULL.
Finally, const qualifiers potentially allow the compiler to do more
optimizations. This being said no benchmarking was done for this patch.

Author: Aleksander Alekseev
Reviewed-by: Bharath Rupireddy, David Rowley
Discussion: https://postgr.es/m/CAApHDvrtVxr+FXEX0VbViCFKDGxA3tWDgw9oFewNXCJMmwLjLg@mail.gmail.com
---
 src/backend/lib/ilist.c |  8 +++---
 src/include/lib/ilist.h | 56 ++++++++++++++++++++---------------------
 2 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/src/backend/lib/ilist.c b/src/backend/lib/ilist.c
index e8ea981176..a1f236a9e1 100644
--- a/src/backend/lib/ilist.c
+++ b/src/backend/lib/ilist.c
@@ -28,7 +28,7 @@
  * Caution: this is O(n); consider using slist_delete_current() instead.
  */
 void
-slist_delete(slist_head *head, slist_node *node)
+slist_delete(slist_head *head, const slist_node *node)
 {
 	slist_node *last = &head->head;
 	slist_node *cur;
@@ -57,7 +57,7 @@ slist_delete(slist_head *head, slist_node *node)
  *		Validate that 'node' is a member of 'head'
  */
 void
-dlist_member_check(dlist_head *head, dlist_node *node)
+dlist_member_check(const dlist_head *head, const dlist_node *node)
 {
 	dlist_iter	iter;
 
@@ -73,7 +73,7 @@ dlist_member_check(dlist_head *head, dlist_node *node)
  * Verify integrity of a doubly linked list
  */
 void
-dlist_check(dlist_head *head)
+dlist_check(const dlist_head *head)
 {
 	dlist_node *cur;
 
@@ -110,7 +110,7 @@ dlist_check(dlist_head *head)
  * Verify integrity of a singly linked list
  */
 void
-slist_check(slist_head *head)
+slist_check(const slist_head *head)
 {
 	slist_node *cur;
 
diff --git a/src/include/lib/ilist.h b/src/include/lib/ilist.h
index 3c543e7c36..6c2b05721b 100644
--- a/src/include/lib/ilist.h
+++ b/src/include/lib/ilist.h
@@ -286,12 +286,12 @@ typedef struct slist_mutable_iter
 /* Prototypes for functions too big to be inline */
 
 /* Caution: this is O(n); consider using slist_delete_current() instead */
-extern void slist_delete(slist_head *head, slist_node *node);
+extern void slist_delete(slist_head *head, const slist_node *node);
 
 #ifdef ILIST_DEBUG
-extern void dlist_member_check(dlist_head *head, dlist_node *node);
-extern void dlist_check(dlist_head *head);
-extern void slist_check(slist_head *head);
+extern void dlist_member_check(const dlist_head *head, const dlist_node *node);
+extern void dlist_check(const dlist_head *head);
+extern void slist_check(const slist_head *head);
 #else
 /*
  * These seemingly useless casts to void are here to keep the compiler quiet
@@ -322,7 +322,7 @@ dlist_init(dlist_head *head)
  * An empty list has either its first 'next' pointer set to NULL, or to itself.
  */
 static inline bool
-dlist_is_empty(dlist_head *head)
+dlist_is_empty(const dlist_head *head)
 {
 	dlist_check(head);
 
@@ -465,7 +465,7 @@ dlist_move_tail(dlist_head *head, dlist_node *node)
  * Caution: unreliable if 'node' is not in the list.
  */
 static inline bool
-dlist_has_next(dlist_head *head, dlist_node *node)
+dlist_has_next(const dlist_head *head, const dlist_node *node)
 {
 	return node->next != &head->head;
 }
@@ -475,7 +475,7 @@ dlist_has_next(dlist_head *head, dlist_node *node)
  * Caution: unreliable if 'node' is not in the list.
  */
 static inline bool
-dlist_has_prev(dlist_head *head, dlist_node *node)
+dlist_has_prev(const dlist_head *head, const dlist_node *node)
 {
 	return node->prev != &head->head;
 }
@@ -484,7 +484,7 @@ dlist_has_prev(dlist_head *head, dlist_node *node)
  * Return the next node in the list (there must be one).
  */
 static inline dlist_node *
-dlist_next_node(dlist_head *head, dlist_node *node)
+dlist_next_node(const dlist_head *head, const dlist_node *node)
 {
 	Assert(dlist_has_next(head, node));
 	return node->next;
@@ -494,7 +494,7 @@ dlist_next_node(dlist_head *head, dlist_node *node)
  * Return previous node in the list (there must be one).
  */
 static inline dlist_node *
-dlist_prev_node(dlist_head *head, dlist_node *node)
+dlist_prev_node(const dlist_head *head, const dlist_node *node)
 {
 	Assert(dlist_has_prev(head, node));
 	return node->prev;
@@ -502,7 +502,7 @@ dlist_prev_node(dlist_head *head, dlist_node *node)
 
 /* internal support function to get address of head element's struct */
 static inline void *
-dlist_head_element_off(dlist_head *head, size_t off)
+dlist_head_element_off(const dlist_head *head, size_t off)
 {
 	Assert(!dlist_is_empty(head));
 	return (char *) head->head.next - off;
@@ -512,14 +512,14 @@ dlist_head_element_off(dlist_head *head, size_t off)
  * Return the first node in the list (there must be one).
  */
 static inline dlist_node *
-dlist_head_node(dlist_head *head)
+dlist_head_node(const dlist_head *head)
 {
 	return (dlist_node *) dlist_head_element_off(head, 0);
 }
 
 /* internal support function to get address of tail element's struct */
 static inline void *
-dlist_tail_element_off(dlist_head *head, size_t off)
+dlist_tail_element_off(const dlist_head *head, size_t off)
 {
 	Assert(!dlist_is_empty(head));
 	return (char *) head->head.prev - off;
@@ -529,7 +529,7 @@ dlist_tail_element_off(dlist_head *head, size_t off)
  * Return the last node in the list (there must be one).
  */
 static inline dlist_node *
-dlist_tail_node(dlist_head *head)
+dlist_tail_node(const dlist_head *head)
 {
 	return (dlist_node *) dlist_tail_element_off(head, 0);
 }
@@ -629,7 +629,7 @@ dclist_init(dclist_head *head)
  *		Returns true if the list is empty, otherwise false.
  */
 static inline bool
-dclist_is_empty(dclist_head *head)
+dclist_is_empty(const dclist_head *head)
 {
 	Assert(dlist_is_empty(&head->dlist) == (head->count == 0));
 	return (head->count == 0);
@@ -773,7 +773,7 @@ dclist_move_tail(dclist_head *head, dlist_node *node)
  * Caution: 'node' must be a member of 'head'.
  */
 static inline bool
-dclist_has_next(dclist_head *head, dlist_node *node)
+dclist_has_next(const dclist_head *head, const dlist_node *node)
 {
 	dlist_member_check(&head->dlist, node);
 	Assert(head->count > 0);
@@ -788,7 +788,7 @@ dclist_has_next(dclist_head *head, dlist_node *node)
  * Caution: 'node' must be a member of 'head'.
  */
 static inline bool
-dclist_has_prev(dclist_head *head, dlist_node *node)
+dclist_has_prev(const dclist_head *head, const dlist_node *node)
 {
 	dlist_member_check(&head->dlist, node);
 	Assert(head->count > 0);
@@ -801,7 +801,7 @@ dclist_has_prev(dclist_head *head, dlist_node *node)
  *		Return the next node in the list (there must be one).
  */
 static inline dlist_node *
-dclist_next_node(dclist_head *head, dlist_node *node)
+dclist_next_node(const dclist_head *head, const dlist_node *node)
 {
 	Assert(head->count > 0);
 
@@ -813,7 +813,7 @@ dclist_next_node(dclist_head *head, dlist_node *node)
  *		Return the prev node in the list (there must be one).
  */
 static inline dlist_node *
-dclist_prev_node(dclist_head *head, dlist_node *node)
+dclist_prev_node(const dclist_head *head, const dlist_node *node)
 {
 	Assert(head->count > 0);
 
@@ -822,7 +822,7 @@ dclist_prev_node(dclist_head *head, dlist_node *node)
 
 /* internal support function to get address of head element's struct */
 static inline void *
-dclist_head_element_off(dclist_head *head, size_t off)
+dclist_head_element_off(const dclist_head *head, size_t off)
 {
 	Assert(!dclist_is_empty(head));
 
@@ -834,7 +834,7 @@ dclist_head_element_off(dclist_head *head, size_t off)
  *		Return the first node in the list (there must be one).
  */
 static inline dlist_node *
-dclist_head_node(dclist_head *head)
+dclist_head_node(const dclist_head *head)
 {
 	Assert(head->count > 0);
 
@@ -843,7 +843,7 @@ dclist_head_node(dclist_head *head)
 
 /* internal support function to get address of tail element's struct */
 static inline void *
-dclist_tail_element_off(dclist_head *head, size_t off)
+dclist_tail_element_off(const dclist_head *head, size_t off)
 {
 	Assert(!dclist_is_empty(head));
 
@@ -854,7 +854,7 @@ dclist_tail_element_off(dclist_head *head, size_t off)
  * Return the last node in the list (there must be one).
  */
 static inline dlist_node *
-dclist_tail_node(dclist_head *head)
+dclist_tail_node(const dclist_head *head)
 {
 	Assert(head->count > 0);
 
@@ -866,7 +866,7 @@ dclist_tail_node(dclist_head *head)
  *		Returns the stored number of entries in 'head'
  */
 static inline uint32
-dclist_count(dclist_head *head)
+dclist_count(const dclist_head *head)
 {
 	Assert(dlist_is_empty(&head->dlist) == (head->count == 0));
 
@@ -929,7 +929,7 @@ slist_init(slist_head *head)
  * Is the list empty?
  */
 static inline bool
-slist_is_empty(slist_head *head)
+slist_is_empty(const slist_head *head)
 {
 	slist_check(head);
 
@@ -977,7 +977,7 @@ slist_pop_head_node(slist_head *head)
  * Check whether 'node' has a following node.
  */
 static inline bool
-slist_has_next(slist_head *head, slist_node *node)
+slist_has_next(const slist_head *head, const slist_node *node)
 {
 	slist_check(head);
 
@@ -988,7 +988,7 @@ slist_has_next(slist_head *head, slist_node *node)
  * Return the next node in the list (there must be one).
  */
 static inline slist_node *
-slist_next_node(slist_head *head, slist_node *node)
+slist_next_node(const slist_head *head, const slist_node *node)
 {
 	Assert(slist_has_next(head, node));
 	return node->next;
@@ -996,7 +996,7 @@ slist_next_node(slist_head *head, slist_node *node)
 
 /* internal support function to get address of head element's struct */
 static inline void *
-slist_head_element_off(slist_head *head, size_t off)
+slist_head_element_off(const slist_head *head, size_t off)
 {
 	Assert(!slist_is_empty(head));
 	return (char *) head->head.next - off;
@@ -1006,7 +1006,7 @@ slist_head_element_off(slist_head *head, size_t off)
  * Return the first node in the list (there must be one).
  */
 static inline slist_node *
-slist_head_node(slist_head *head)
+slist_head_node(const slist_head *head)
 {
 	return (slist_node *) slist_head_element_off(head, 0);
 }
-- 
2.38.0

