Currently the StringInfo package provides StringInfo object creation
API with fixed length initial allocation size (1024 bytes). However,
if we want to allocate much smaller size of initial allocation, this
is waste of space.
Background: While working on this:
https://www.postgresql.org/message-id/20241219.151950.488757175470671324.ishii%40postgresql.org
I need to create lots of StringInfo many (like 100k) objects if a
Window frame has that number of rows. In this case postgres allocates
1024 * 100k = 97.7MB of memory, which is too much because I usually
only need 10 or so bytes for each StringInfo data buffer.
To solve the problem I need to hack the internal of StringInfo object
like this.
len = 10;
str = makeStringInfo();
pfree(encoded_str->data);
str->data = (char *)palloc0(len);
str->maxlen = len;
This is not only ugly but breaks interface boundary. If we have
another API like makeStringInfoWithSize(), I could do that in much
better and simple way:
len = 10;
str = makeStringInfoWithSize(len);
Attached is a patch to implement it. In the patch I add two new APIs.
extern StringInfo makeStringInfoWithSize(int size);
extern void initStringInfoWithSize(StringInfo str, int size);
Maybe I could re-invent the wheel by copying stringinfo.c, but I think
there are some uses cases like me, and it could justify in adding more
code to stringinfo.c.
Best reagards,
--
Tatsuo Ishii
SRA OSS K.K.
English: http://www.sraoss.co.jp/index_en/
Japanese:http://www.sraoss.co.jp
diff --git a/src/common/stringinfo.c b/src/common/stringinfo.c
index 6192e65477..e740b499fa 100644
--- a/src/common/stringinfo.c
+++ b/src/common/stringinfo.c
@@ -46,6 +46,24 @@ makeStringInfo(void)
return res;
}
+/*
+ * makeStringInfoWithSize
+ *
+ * Create an empty 'StringInfoData' & return a pointer to it.
+ * The initial memory allocation size is specified by 'size'.
+ */
+StringInfo
+makeStringInfoWithSize(int size)
+{
+ StringInfo res;
+
+ res = (StringInfo) palloc(sizeof(StringInfoData));
+
+ initStringInfoWithSize(res, size);
+
+ return res;
+}
+
/*
* initStringInfo
*
@@ -57,6 +75,20 @@ initStringInfo(StringInfo str)
{
int size = 1024; /* initial default buffer size */
+ initStringInfoWithSize(str, size);
+}
+
+/*
+ * initStringInfoWithSize
+ *
+ * Same as initStringInfo except accepting additional 'size' argument for the
+ * initial memory allocation.
+ */
+void
+initStringInfoWithSize(StringInfo str, int size)
+{
+ Assert(size > 0);
+
str->data = (char *) palloc(size);
str->maxlen = size;
resetStringInfo(str);
diff --git a/src/include/lib/stringinfo.h b/src/include/lib/stringinfo.h
index cd9632e3fc..5d603aa0cc 100644
--- a/src/include/lib/stringinfo.h
+++ b/src/include/lib/stringinfo.h
@@ -60,6 +60,10 @@ typedef StringInfoData *StringInfo;
* StringInfo stringptr = makeStringInfo();
* Both the StringInfoData and the data buffer are palloc'd.
*
+ * StringInfo stringptr = makeStringInfoWithSize(size);
+ * Both the StringInfoData and the data buffer are palloc'd.
+ * The data buffer is allocated with size 'size'.
+ *
* StringInfoData string;
* initStringInfo(&string);
* The data buffer is palloc'd but the StringInfoData is just local.
@@ -106,6 +110,13 @@ typedef StringInfoData *StringInfo;
*/
extern StringInfo makeStringInfo(void);
+/*------------------------
+ * makeStringInfo
+ * Create an empty 'StringInfoData' & return a pointer to it.
+ * The data buffer is allocated with size 'size'.
+ */
+extern StringInfo makeStringInfoWithSize(int size);
+
/*------------------------
* initStringInfo
* Initialize a StringInfoData struct (with previously undefined contents)
@@ -113,6 +124,14 @@ extern StringInfo makeStringInfo(void);
*/
extern void initStringInfo(StringInfo str);
+/*------------------------
+ * initStringInfoWithSize
+ * Initialize a StringInfoData struct (with previously undefined contents)
+ * to describe an empty string.
+ * The data buffer is allocated with size 'size'.
+ */
+extern void initStringInfoWithSize(StringInfo str, int size);
+
/*------------------------
* initReadOnlyStringInfo
* Initialize a StringInfoData struct from an existing string without copying