0001-use-simple-ptr-list_topup_patch

application/octet-stream

Filename: 0001-use-simple-ptr-list_topup_patch
Type: application/octet-stream
Part: 0
Message: RE: [PoC] pg_upgrade: allow to upgrade publisher node
From 4302004aa9d6f5d7f60b10be8821b31caa1196ab Mon Sep 17 00:00:00 2001
From: Hou Zhijie <houzj.fnst@cn.fujitsu.com>
Date: Wed, 6 Sep 2023 10:21:37 +0800
Subject: [PATCH] use simple ptr list

---
 src/bin/pg_upgrade/function.c | 123 ++++++++--------------------------
 1 file changed, 27 insertions(+), 96 deletions(-)

diff --git a/src/bin/pg_upgrade/function.c b/src/bin/pg_upgrade/function.c
index b00c7a8e41..c579891bf6 100644
--- a/src/bin/pg_upgrade/function.c
+++ b/src/bin/pg_upgrade/function.c
@@ -11,28 +11,10 @@
 
 #include "access/transam.h"
 #include "catalog/pg_language_d.h"
+#include "fe_utils/simple_list.h"
 #include "fe_utils/string_utils.h"
 #include "pg_upgrade.h"
 
-/*
- * Structures for listing up unique output plugins.
- *
- * XXX: these are not needed if we remove the function get_output_plugins().
- * See comments atop it.
- */
-typedef struct plugin_list_head
-{
-	struct plugin_list *head;
-	int			length;
-} plugin_list_head;
-
-typedef struct plugin_list
-{
-	int			dbnum;
-	char	   *plugin;
-	struct plugin_list *next;
-} plugin_list;
-
 /*
  * qsort comparator for pointers to library names
  *
@@ -62,60 +44,6 @@ library_name_compare(const void *p1, const void *p2)
 			((const LibraryInfo *) p2)->dbnum;
 }
 
-
-/* Fetch list's length */
-static int
-plugin_list_length(plugin_list_head *listhead)
-{
-	return listhead ? listhead->length : 0;
-}
-
-/* Has the given plugin already been listed? */
-static bool
-is_plugin_unique(plugin_list_head *listhead, const char *plugin)
-{
-	plugin_list *point;
-
-	/* Quick return if the head is NULL */
-	if (listhead == NULL)
-		return true;
-
-	/* Seek the plugin list */
-	for (point = listhead->head; point; point = point->next)
-	{
-		if (strcmp(point->plugin, plugin) == 0)
-			return false;
-	}
-
-	return true;
-}
-
-/* Add an item to a plugin_list. */
-static void
-add_plugin_list_item(plugin_list_head **listhead, int dbnum, const char *plugin)
-{
-	plugin_list *newentry = (plugin_list *) pg_malloc(sizeof(plugin_list));
-	plugin_list *oldentry;
-
-	newentry->dbnum = dbnum;
-	newentry->plugin = pg_strdup(plugin);
-
-	/* Initialize the header if not yet */
-	if (*listhead == NULL)
-		*listhead = (plugin_list_head *) pg_malloc0(sizeof(plugin_list_head));
-
-	/*
-	 * Set the new entry as the head of the list. We do not have to consider
-	 * the ordering because they are sorted later.
-	 */
-	oldentry = (*listhead)->head;
-	(*listhead)->head = newentry;
-	newentry->next = oldentry;
-
-	/* Increment the list for plugin_list_length() */
-	(*listhead)->length++;
-}
-
 /*
  * Load the list of unique output plugins.
  *
@@ -126,19 +54,25 @@ add_plugin_list_item(plugin_list_head **listhead, int dbnum, const char *plugin)
  * the same library. The above means that we can arrange output plugins without
  * considering their uniqueness, so that we can remove this function.
  */
-static plugin_list_head *
-get_output_plugins(void)
+static SimpleStringList **
+get_output_plugins(int *pluginnum)
 {
-	plugin_list_head *head = NULL;
+	SimpleStringList **plugins_perdb;
 	int			dbnum;
 
+	Assert(pluginnum);
+	*pluginnum = 0;
+
 	/* Quick return if there are no logical slots to be migrated. */
 	if (count_old_cluster_logical_slots() == 0)
 		return NULL;
 
+	plugins_perdb = pg_malloc0_array(SimpleStringList *, old_cluster.dbarr.ndbs);
+
 	for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
 	{
 		LogicalSlotInfoArr *slot_arr = &old_cluster.dbarr.dbs[dbnum].slot_arr;
+		SimpleStringList *pnames = pg_malloc0_object(SimpleStringList);
 		int			slotnum;
 
 		for (slotnum = 0; slotnum < slot_arr->nslots; slotnum++)
@@ -146,12 +80,17 @@ get_output_plugins(void)
 			LogicalSlotInfo *slot = &slot_arr->slots[slotnum];
 
 			/* Add to the list if the plugin has not been listed yet */
-			if (is_plugin_unique(head, slot->plugin))
-				add_plugin_list_item(&head, dbnum, slot->plugin);
+			if (!simple_string_list_member(pnames, slot->plugin))
+			{
+				simple_string_list_append(pnames, pg_strdup(slot->plugin));
+				*pluginnum++;
+			}
 		}
+
+		plugins_perdb[dbnum] = pnames;
 	}
 
-	return head;
+	return plugins_perdb;
 }
 
 /*
@@ -168,7 +107,8 @@ get_loadable_libraries(void)
 	PGresult  **ress;
 	int			totaltups;
 	int			dbnum;
-	plugin_list_head *output_plugins = get_output_plugins();
+	int			pluginnum;
+	SimpleStringList **output_plugins = get_output_plugins(&pluginnum);
 
 	ress = (PGresult **) pg_malloc(old_cluster.dbarr.ndbs * sizeof(PGresult *));
 	totaltups = 0;
@@ -199,13 +139,8 @@ get_loadable_libraries(void)
 	/*
 	 * Allocate a minimal memory for extensions and logical replication output
 	 * plugins.
-	 *
-	 * XXX: As mentioned in comments atop get_output_plugins(), we may not
-	 * have to consider the uniqueness of entries. If so, we can use
-	 * count_old_cluster_logical_slots() instead of plugin_list_length().
 	 */
-	os_info.libraries = (LibraryInfo *) pg_malloc(
-												  (totaltups + plugin_list_length(output_plugins)) * sizeof(LibraryInfo));
+	os_info.libraries = (LibraryInfo *) pg_malloc((totaltups + pluginnum) * sizeof(LibraryInfo));
 	totaltups = 0;
 
 	for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
@@ -213,7 +148,7 @@ get_loadable_libraries(void)
 		PGresult   *res = ress[dbnum];
 		int			ntups;
 		int			rowno;
-		plugin_list *point;
+		SimpleStringListCell *cell;
 
 		ntups = PQntuples(res);
 		for (rowno = 0; rowno < ntups; rowno++)
@@ -229,19 +164,15 @@ get_loadable_libraries(void)
 
 		/*
 		 * If the old cluster has logical replication slots, plugins used by
-		 * them must be also stored. It must be done only once, so do it at
-		 * dbnum == 0 case.
+		 * them must be also stored.
 		 */
-		if (output_plugins == NULL)
-			continue;
-
-		if (dbnum != 0)
+		if (output_plugins[dbnum] == NULL)
 			continue;
 
-		for (point = output_plugins->head; point; point = point->next)
+		for (cell = output_plugins[dbnum]->head; cell; cell = cell->next)
 		{
-			os_info.libraries[totaltups].name = pg_strdup(point->plugin);
-			os_info.libraries[totaltups].dbnum = point->dbnum;
+			os_info.libraries[totaltups].name = pg_strdup(cell->val);
+			os_info.libraries[totaltups].dbnum = dbnum;
 
 			totaltups++;
 		}
-- 
2.30.0.windows.2