Tarantool development patches archive
 help / color / mirror / Atom feed
From: Roman Khabibov <roman.habibov@tarantool.org>
To: Nikita Pettik <korablev@tarantool.org>
Cc: tarantool-patches@dev.tarantool.org, v.shpilevoy@tarantool.org
Subject: Re: [Tarantool-patches] [PATCH v4 4/6] sql: use parser's region of "index" array
Date: Tue, 29 Sep 2020 02:29:26 +0300	[thread overview]
Message-ID: <8F4523FC-8185-468D-A784-C3A81EFF32C8@tarantool.org> (raw)
In-Reply-To: <20200916133024.GC10599@tarantool.org>

Hi! Thanks for the review.

> On Sep 16, 2020, at 16:30, Nikita Pettik <korablev@tarantool.org> wrote:
> 
> On 12 Sep 00:51, Roman Khabibov wrote:
>> Allocate memory for the "index" array of ephemeral space on the
>> parser's region instead of a heap as it was before. Fixed a memory
>> leak that realloc() generated.
>> 
>> Needed for #3075
> 
> Why it is related to 3075??
Fixed to -> 2349. Due to this patch, I avoid malloc inside sql_space_shallow_copy.

>> ---
>> src/box/sql/build.c | 42 +++++++++++++++++++++++++++++++-----------
>> 1 file changed, 31 insertions(+), 11 deletions(-)
>> 
>> diff --git a/src/box/sql/build.c b/src/box/sql/build.c
>> index 6cc76bb77..d1d240315 100644
>> --- a/src/box/sql/build.c
>> +++ b/src/box/sql/build.c
>> @@ -2226,29 +2226,49 @@ vdbe_emit_new_sec_index_id(struct Parse *parse, uint32_t space_id,
>> }
>> 
>> /**
>> - * Add new index to table's indexes list.
>> + * Add new index to ephemeral @a space's "index" array. Reallocate
>> + * memory on @a region if needed.
>> + *
>>  * We follow convention that PK comes first in list.
>>  *
>> + * @param region Region (on parser).
>>  * @param space Space to which belongs given index.
>>  * @param index Index to be added to list.
>>  */
>> static void
>> -table_add_index(struct space *space, struct index *index)
>> +sql_space_add_index(struct region *region, struct space *space,
>> +		    struct index *index)
>> {
>> 	uint32_t idx_count = space->index_count;
>> -	size_t indexes_sz = sizeof(struct index *) * (idx_count + 1);
>> -	struct index **idx = (struct index **) realloc(space->index,
>> -						       indexes_sz);
>> -	if (idx == NULL) {
>> -		diag_set(OutOfMemory, indexes_sz, "realloc", "idx");
>> -		return;
>> -	}
>> -	space->index = idx;
>> +	size_t size = 0;
>> +	struct index **idx = NULL;
>> +	if (idx_count == 0) {
>> +		idx = region_alloc_array(region, typeof(struct index *), 1,
>> +					 &size);
>> +		if (idx == NULL)
>> +			goto alloc_error;
>> +	/*
>> +	 * Reallocate each time the idx_count becomes equal to the
>> +	 * power of two.
>> +	 */
>> +	} else if ((idx_count & (idx_count - 1)) == 0) {
>> +		idx = region_alloc_array(region, typeof(struct index *),
>> +					 idx_count * 2, &size);
>> +		if (idx == NULL)
>> +			goto alloc_error;
>> +		memcpy(idx, space->index, idx_count * sizeof(struct index *));
>> +	}
>> +	if (idx != NULL)
>> +		space->index = idx;
> 
> DOes it make any sense? Why not simply call ::free (in case there really
> was memleak)?
It was a memleak, really. I checked it by valgrind.

This is the main reason. So that when destroying the parser, you don't have
to check whether it was CREATE or ALTER, whether malloc or realloc was called
inside build.c, and don't call free. The parser region is well suited for
this task.

>> 	/* Make sure that PK always comes as first member. */
>> 	if (index->def->iid == 0 && idx_count != 0)
>> 		SWAP(space->index[0], index);
>> 	space->index[space->index_count++] = index;
>> 	space->index_id_max =  MAX(space->index_id_max, index->def->iid);;
>> +	return;
>> +
>> +alloc_error:
>> +	diag_set(OutOfMemory, size, "region_alloc_array", "idx");
>> }
>> 
>> int
>> @@ -2717,7 +2737,7 @@ sql_create_index(struct Parse *parse) {
>> 
>> 	if (tbl_name != NULL)
>> 		goto exit_create_index;
>> -	table_add_index(space, index);
>> +	sql_space_add_index(&parse->region, space, index);
>> 	index = NULL;
>> 
>> 	/* Clean up before exiting. */
>> -- 
>> 2.24.3 (Apple Git-128)
>> 


commit 177c4389af647677afcce9fa58b12f00e398fbe9
Author: Roman Khabibov <roman.habibov@tarantool.org>
Date:   Thu Sep 3 14:26:47 2020 +0300

    sql: use parser's region of "index" array
    
    Allocate memory for the "index" array of ephemeral space on the
    parser's region instead of a heap as it was before. Fixed a memory
    leak that realloc() generated.
    
    Needed for #2349

diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index 6cc76bb77..d1d240315 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -2226,29 +2226,49 @@ vdbe_emit_new_sec_index_id(struct Parse *parse, uint32_t space_id,
 }
 
 /**
- * Add new index to table's indexes list.
+ * Add new index to ephemeral @a space's "index" array. Reallocate
+ * memory on @a region if needed.
+ *
  * We follow convention that PK comes first in list.
  *
+ * @param region Region (on parser).
  * @param space Space to which belongs given index.
  * @param index Index to be added to list.
  */
 static void
-table_add_index(struct space *space, struct index *index)
+sql_space_add_index(struct region *region, struct space *space,
+		    struct index *index)
 {
 	uint32_t idx_count = space->index_count;
-	size_t indexes_sz = sizeof(struct index *) * (idx_count + 1);
-	struct index **idx = (struct index **) realloc(space->index,
-						       indexes_sz);
-	if (idx == NULL) {
-		diag_set(OutOfMemory, indexes_sz, "realloc", "idx");
-		return;
-	}
-	space->index = idx;
+	size_t size = 0;
+	struct index **idx = NULL;
+	if (idx_count == 0) {
+		idx = region_alloc_array(region, typeof(struct index *), 1,
+					 &size);
+		if (idx == NULL)
+			goto alloc_error;
+	/*
+	 * Reallocate each time the idx_count becomes equal to the
+	 * power of two.
+	 */
+	} else if ((idx_count & (idx_count - 1)) == 0) {
+		idx = region_alloc_array(region, typeof(struct index *),
+					 idx_count * 2, &size);
+		if (idx == NULL)
+			goto alloc_error;
+		memcpy(idx, space->index, idx_count * sizeof(struct index *));
+	}
+	if (idx != NULL)
+		space->index = idx;
 	/* Make sure that PK always comes as first member. */
 	if (index->def->iid == 0 && idx_count != 0)
 		SWAP(space->index[0], index);
 	space->index[space->index_count++] = index;
 	space->index_id_max =  MAX(space->index_id_max, index->def->iid);;
+	return;
+
+alloc_error:
+	diag_set(OutOfMemory, size, "region_alloc_array", "idx");
 }
 
 int
@@ -2717,7 +2737,7 @@ sql_create_index(struct Parse *parse) {
 
 	if (tbl_name != NULL)
 		goto exit_create_index;
-	table_add_index(space, index);
+	sql_space_add_index(&parse->region, space, index);
 	index = NULL;
 
 	/* Clean up before exiting. */

  reply	other threads:[~2020-09-28 23:29 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-11 21:51 [Tarantool-patches] [PATCH v4 0/6] Support column addition Roman Khabibov
2020-09-11 21:51 ` [Tarantool-patches] [PATCH v4 1/6] sql: rename TK_COLUMN to TK_COLUMN_NAME Roman Khabibov
2020-09-16 13:17   ` Nikita Pettik
2020-09-28 23:29     ` Roman Khabibov
2020-09-11 21:51 ` [Tarantool-patches] [PATCH v4 2/6] sql: refactor create_table_def and parse Roman Khabibov
2020-09-16 13:27   ` Nikita Pettik
2020-09-17 14:43     ` Vladislav Shpilevoy
2020-09-18 12:31       ` Nikita Pettik
2020-09-18 13:21         ` Roman Khabibov
2020-09-28 23:29     ` Roman Khabibov
2020-09-17 14:43   ` Vladislav Shpilevoy
2020-10-02 22:08     ` Vladislav Shpilevoy
2020-10-03 21:37     ` Roman Khabibov
2020-10-04 13:45       ` Vladislav Shpilevoy
2020-10-04 21:44         ` Roman Khabibov
2020-10-05 21:22           ` Vladislav Shpilevoy
2020-10-07 13:53             ` Roman Khabibov
2020-10-07 22:35               ` Vladislav Shpilevoy
2020-10-08 10:32                 ` Roman Khabibov
2020-09-17 15:16   ` Vladislav Shpilevoy
2020-10-02 22:08     ` Vladislav Shpilevoy
2020-09-11 21:51 ` [Tarantool-patches] [PATCH v4 3/6] schema: add box_space_field_MAX Roman Khabibov
2020-09-11 21:51 ` [Tarantool-patches] [PATCH v4 4/6] sql: use parser's region of "index" array Roman Khabibov
2020-09-16 13:30   ` Nikita Pettik
2020-09-28 23:29     ` Roman Khabibov [this message]
2020-09-17 14:53   ` Vladislav Shpilevoy
2020-09-23 14:25     ` Roman Khabibov
2020-09-24 21:30       ` Vladislav Shpilevoy
2020-10-05 21:22   ` Vladislav Shpilevoy
2020-10-07 13:53     ` Roman Khabibov
2020-09-11 21:51 ` [Tarantool-patches] [PATCH v4 5/6] box: disallow to modify format of a view Roman Khabibov
2020-09-16 13:37   ` Nikita Pettik
2020-09-22 15:59     ` Roman Khabibov
2020-09-17 15:01   ` Vladislav Shpilevoy
2020-09-22 15:59     ` Roman Khabibov
2020-09-11 21:51 ` [Tarantool-patches] [PATCH v4 6/6] sql: support column addition Roman Khabibov
2020-09-16 20:18   ` Nikita Pettik
2020-09-17 15:19     ` Vladislav Shpilevoy
2020-09-18 12:59       ` Nikita Pettik
2020-09-28 23:28         ` Roman Khabibov
2020-10-02 22:08           ` Vladislav Shpilevoy
2020-10-03 21:37             ` Roman Khabibov
2020-09-17 15:45   ` Vladislav Shpilevoy
2020-10-04 13:45   ` Vladislav Shpilevoy
2020-10-04 21:44     ` Roman Khabibov
2020-09-11 22:00 ` [Tarantool-patches] [PATCH v4 0/6] Support " Roman Khabibov
2020-10-08 22:07 ` Vladislav Shpilevoy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8F4523FC-8185-468D-A784-C3A81EFF32C8@tarantool.org \
    --to=roman.habibov@tarantool.org \
    --cc=korablev@tarantool.org \
    --cc=tarantool-patches@dev.tarantool.org \
    --cc=v.shpilevoy@tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH v4 4/6] sql: use parser'\''s region of "index" array' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox