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. */
next prev parent 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