[patches] [PATCH 3/3] sql: make OP_MakeRecord use region allocator

Nikita Pettik korablev at tarantool.org
Mon Feb 12 17:06:29 MSK 2018


VDBE used ordinary malloc to allocate memory for tuples. However,
immediately before calling insertion method to space, tuples were copied
into region memory. Thus, excess copy took place. This patch makes
OP_MakeRecord opcode allocate memory on region right away.

Closes #3021
---
 src/box/sql.c      | 14 ++++----------
 src/box/sql/vdbe.c | 15 ++++++++-------
 2 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/src/box/sql.c b/src/box/sql.c
index 1ed2490c7..d45d7e75f 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -501,21 +501,15 @@ static int insertOrReplace(BtCursor *pCur, const CursorPayload *pX,
 	assert(operationType == TARANTOOL_INDEX_INSERT ||
 	       operationType == TARANTOOL_INDEX_REPLACE);
 
-	char *buf = (char*)region_alloc(&fiber()->gc, pX->nKey);
-	if (buf == NULL) {
-		diag_set(OutOfMemory, pX->nKey, "region", "buf");
-		return SQLITE_TARANTOOL_ERROR;
-	}
-
-	memcpy(buf, pX->pKey, pX->nKey);
 	int space_id = SQLITE_PAGENO_TO_SPACEID(pCur->pgnoRoot);
-
 	int rc;
 	if (operationType == TARANTOOL_INDEX_INSERT) {
-		rc = box_insert(space_id, buf, (const char *)buf + pX->nKey,
+		rc = box_insert(space_id, pX->pKey,
+				(const char *)pX->pKey + pX->nKey,
 				NULL /* result */);
 	} else {
-		rc = box_replace(space_id, buf, (const char *)buf + pX->nKey,
+		rc = box_replace(space_id, pX->pKey,
+				 (const char *)pX->pKey + pX->nKey,
 				 NULL /* result */);
 	}
 
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index ddd849903..66a9fd14d 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -2737,19 +2737,20 @@ case OP_MakeRecord: {
 		goto too_big;
 	}
 
-	/* Make sure the output register has a buffer large enough to store
-	 * the new record. The output register (pOp->p3) is not allowed to
-	 * be one of the input registers (because the following call to
-	 * sqlite3VdbeMemClearAndResize() could clobber the value before it is used).
+	/* Allocate memory on the region for the tuple
+	 * to be passed to Tarantool. Before that, make
+	 * sure previously allocated memory has gone.
 	 */
-	if (sqlite3VdbeMemClearAndResize(pOut, (int)nByte)) {
+	sqlite3VdbeMemRelease(pOut);
+	pOut->n = nByte;
+	pOut->z = region_alloc(&fiber()->gc, nByte);
+	if (pOut->z == NULL)
 		goto no_mem;
-	}
 
 	/* Write the record */
 	assert(pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor));
 	pOut->n = sqlite3VdbeMsgpackRecordPut((u8 *)pOut->z, pData0, nField);
-	pOut->flags = MEM_Blob;
+	pOut->flags = MEM_Blob | MEM_Ephem;
 	REGISTER_TRACE(pOp->p3, pOut);
 	UPDATE_MAX_BLOBSIZE(pOut);
 	break;
-- 
2.15.1




More information about the Tarantool-patches mailing list