From 1c9e8ce0d0fff5a110df8053142742fcd240c1c5 Mon Sep 17 00:00:00 2001
From: Tatsuo Ishii <ishii@postgresql.org>
Date: Sun, 5 Jan 2025 17:01:09 +0900
Subject: [PATCH v2] Add new StringInfo APIs to allow callers to specify buffer
 size.

Previously StringInfo APIs allocated buffers with fixed initial
allocation size of 1024 bytes. This may be too large and inappropriate
for some callers that can do with smaller memory buffers. To fix this,
introduce new APIs that allow callers to specify initial buffer size.

extern StringInfo makeStringInfoExt(int initsize);
extern void initStringInfoExt(StringInfo str, int initsize);

Existing APIs (makeStringInfo() and initStringInfo()) are now macros
to call makeStringInfoExtended() and initStringInfoExtended(),
respectively, with the default buffer size of 1024.
---
 src/common/stringinfo.c      | 20 ++++++++++++--------
 src/include/lib/stringinfo.h | 33 ++++++++++++++++++++++++++++++---
 2 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/src/common/stringinfo.c b/src/common/stringinfo.c
index 55d2fbb864d..3c369eecd02 100644
--- a/src/common/stringinfo.c
+++ b/src/common/stringinfo.c
@@ -30,35 +30,39 @@
 
 
 /*
- * makeStringInfo
+ * makeStringInfoExt(int initsize)
  *
  * Create an empty 'StringInfoData' & return a pointer to it.
+ * The initial memory allocation size is specified by 'initsize'.
  */
 StringInfo
-makeStringInfo(void)
+makeStringInfoExt(int initsize)
 {
 	StringInfo	res;
 
+	Assert(initsize > 0);
+
 	res = (StringInfo) palloc(sizeof(StringInfoData));
 
-	initStringInfo(res);
+	initStringInfoExt(res, initsize);
 
 	return res;
 }
 
 /*
- * initStringInfo
+ * initStringInfoExt
  *
  * Initialize a StringInfoData struct (with previously undefined contents)
  * to describe an empty string.
+ * The initial memory allocation size is specified by 'initsize'.
  */
 void
-initStringInfo(StringInfo str)
+initStringInfoExt(StringInfo str, int initsize)
 {
-	int			size = 1024;	/* initial default buffer size */
+	Assert(initsize > 0);
 
-	str->data = (char *) palloc(size);
-	str->maxlen = size;
+	str->data = (char *) palloc(initsize);
+	str->maxlen = initsize;
 	resetStringInfo(str);
 }
 
diff --git a/src/include/lib/stringinfo.h b/src/include/lib/stringinfo.h
index 335208a9fda..4c8bab88a48 100644
--- a/src/include/lib/stringinfo.h
+++ b/src/include/lib/stringinfo.h
@@ -55,11 +55,15 @@ typedef StringInfoData *StringInfo;
 
 
 /*------------------------
- * There are four ways to create a StringInfo object initially:
+ * There are six ways to create a StringInfo object initially:
  *
  * StringInfo stringptr = makeStringInfo();
  *		Both the StringInfoData and the data buffer are palloc'd.
  *
+ * StringInfo stringptr = makeStringInfoExt(initsize);
+ *		Same as makeStringInfo except the data buffer is allocated
+ *		with size 'initsize'.
+ *
  * StringInfoData string;
  * initStringInfo(&string);
  *		The data buffer is palloc'd but the StringInfoData is just local.
@@ -67,6 +71,11 @@ typedef StringInfoData *StringInfo;
  *		only live as long as the current routine.
  *
  * StringInfoData string;
+ * initStringInfoExt(&string, initsize);
+ *		Same as initStringInfo except the data buffer is allocated
+ *		with size 'initsize'.
+ *
+ * StringInfoData string;
  * initReadOnlyStringInfo(&string, existingbuf, len);
  *		The StringInfoData's data field is set to point directly to the
  *		existing buffer and the StringInfoData's len is set to the given len.
@@ -100,18 +109,36 @@ typedef StringInfoData *StringInfo;
  *-------------------------
  */
 
+#define STRINGINFO_DEFAULT_SIZE 1024	/* default initial allocation size */
+#define STRINGINFO_SMALL_SIZE 64	/* small initial allocation size */
+
 /*------------------------
  * makeStringInfo
  * Create an empty 'StringInfoData' & return a pointer to it.
  */
-extern StringInfo makeStringInfo(void);
+#define makeStringInfo()	makeStringInfoExt(STRINGINFO_DEFAULT_SIZE)
+
+/*------------------------
+ * makeStringInfoExt
+ * Create an empty 'StringInfoData' & return a pointer to it.
+ * The data buffer is allocated with size 'initsize'.
+ */
+extern StringInfo makeStringInfoExt(int initsize);
 
 /*------------------------
  * initStringInfo
  * Initialize a StringInfoData struct (with previously undefined contents)
  * to describe an empty string.
  */
-extern void initStringInfo(StringInfo str);
+#define initStringInfo(str)	initStringInfoExt(str, STRINGINFO_DEFAULT_SIZE)
+
+/*------------------------
+ * initStringInfoExt
+ * Initialize a StringInfoData struct (with previously undefined contents) to
+ * describe an empty string. The data buffer is allocated with size
+ * 'initsize'.
+ */
+extern void initStringInfoExt(StringInfo str, int initsize);
 
 /*------------------------
  * initReadOnlyStringInfo
-- 
2.25.1

