[Tarantool-patches] [PATCH v1 04/13] sql: introduce mem_append()

imeevma at tarantool.org imeevma at tarantool.org
Fri Sep 10 19:02:00 MSK 2021


This patch introduces function mem_append(). This function appends the
given string to the end of the STRING or VARBINARY contained in MEM.
In case MEM needs to increase the size of allocated memory, additional
memory is allocated in an attempt to reduce the total number of
allocations. The main use of this function is to add multiple strings to
a single MEM.

Needed for #4145
---
 src/box/sql/mem.c     | 19 +++++++++++++++++++
 src/box/sql/mem.h     |  8 ++++++++
 src/box/sql/vdbeaux.c |  9 ++-------
 3 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c
index b7af00723..ea116cb50 100644
--- a/src/box/sql/mem.c
+++ b/src/box/sql/mem.c
@@ -1953,6 +1953,25 @@ mem_move(struct Mem *to, struct Mem *from)
 	from->zMalloc = NULL;
 }
 
+int
+mem_append(struct Mem *mem, const char *value, uint32_t len)
+{
+	assert((mem->type & (MEM_TYPE_BIN | MEM_TYPE_STR)) != 0);
+	int new_size = mem->n + len;
+	if (((mem->flags & (MEM_Static | MEM_Dyn | MEM_Ephem)) != 0) ||
+	    mem->szMalloc < new_size) {
+		/*
+		 * Force exponential buffer size growth to avoid having to call
+		 * this routine too often.
+		 */
+		if (sqlVdbeMemGrow(mem, new_size + mem->n, 1) != 0)
+			return -1;
+	}
+	memcpy(&mem->z[mem->n], value, len);
+	mem->n = new_size;
+	return 0;
+}
+
 int
 mem_concat(struct Mem *a, struct Mem *b, struct Mem *result)
 {
diff --git a/src/box/sql/mem.h b/src/box/sql/mem.h
index 0da45b8af..54a1e931b 100644
--- a/src/box/sql/mem.h
+++ b/src/box/sql/mem.h
@@ -597,6 +597,14 @@ mem_copy_as_ephemeral(struct Mem *to, const struct Mem *from);
 void
 mem_move(struct Mem *to, struct Mem *from);
 
+/**
+ * Append the given string to the end of the STRING or VARBINARY contained in
+ * MEM. In case MEM needs to increase the size of allocated memory, additional
+ * memory is allocated in an attempt to reduce the total number of allocations.
+ */
+int
+mem_append(struct Mem *mem, const char *value, uint32_t len);
+
 /**
  * Concatenate strings or binaries from the first and the second MEMs and write
  * to the result MEM. In case the first MEM or the second MEM is NULL, the
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index e2dcc72ab..482dcca0c 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -1302,14 +1302,9 @@ sqlVdbeList(Vdbe * p)
 					if (mem_copy_bin(pSub, bin, size) != 0)
 						return -1;
 				} else if (j == nSub) {
-					struct Mem tmp;
-					mem_create(&tmp);
-					uint32_t size = sizeof(SubProgram *);
 					char *bin = (char *)&pOp->p4.pProgram;
-					mem_set_bin_ephemeral(&tmp, bin, size);
-					int rc = mem_concat(pSub, &tmp, pSub);
-					mem_destroy(&tmp);
-					if (rc != 0)
+					uint32_t size = sizeof(SubProgram *);
+					if (mem_append(pSub, bin, size) != 0)
 						return -1;
 				}
 			}
-- 
2.25.1



More information about the Tarantool-patches mailing list