From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 27EE425007 for ; Mon, 12 Aug 2019 19:03:07 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id TBCCWLJS29yK for ; Mon, 12 Aug 2019 19:03:07 -0400 (EDT) Received: from smtp55.i.mail.ru (smtp55.i.mail.ru [217.69.128.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id CBD2425219 for ; Mon, 12 Aug 2019 19:03:06 -0400 (EDT) Received: by smtp55.i.mail.ru with esmtpa (envelope-from ) id 1hxJLF-0007dc-3u for tarantool-patches@freelists.org; Tue, 13 Aug 2019 02:03:05 +0300 From: Vladislav Shpilevoy Subject: [tarantool-patches] [PATCH 09/13] tuple: account the whole array in field.data and size Date: Tue, 13 Aug 2019 01:05:19 +0200 Message-Id: <7b6088916aa3f4aacefcf9bb02d81ba732d190a6.1565649886.git.v.shpilevoy@tarantool.org> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-Help: List-Unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-Subscribe: List-Owner: List-post: List-Archive: To: tarantool-patches@freelists.org Before the patch a struct field object, describing an array, didn't account array header in its size and data. Indeed, it was not needed, because anyway updates could be only 'flat', and the header was regenerated anyway. But after next patches an array update may be not on the top level of an update tree. And its parent node with the current way of accounting would not be able to see exact borders of each child. Part of #1261 --- src/box/tuple_update.c | 28 ++++++++++++++++------------ src/box/update/update_array.c | 9 +++++---- src/box/update/update_field.h | 6 ++++-- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/box/tuple_update.c b/src/box/tuple_update.c index 87946919d..81e1f7e97 100644 --- a/src/box/tuple_update.c +++ b/src/box/tuple_update.c @@ -193,11 +193,12 @@ update_read_ops(struct tuple_update *update, const char *expr, * @retval -1 Error. */ static int -update_do_ops(struct tuple_update *update, const char *old_data, - const char *old_data_end, uint32_t part_count) +update_do_ops(struct tuple_update *update, const char *header, + const char *old_data, const char *old_data_end, + uint32_t part_count) { - if (update_array_create(&update->root_array, old_data, old_data_end, - part_count) != 0) + if (update_array_create(&update->root_array, header, old_data, + old_data_end, part_count) != 0) return -1; struct update_op *op = update->ops; struct update_op *ops_end = op + update->op_count; @@ -214,12 +215,12 @@ update_do_ops(struct tuple_update *update, const char *old_data, * and it is enough to simply write the error to the log. */ static int -upsert_do_ops(struct tuple_update *update, const char *old_data, - const char *old_data_end, uint32_t part_count, - bool suppress_error) +upsert_do_ops(struct tuple_update *update, const char *header, + const char *old_data, const char *old_data_end, + uint32_t part_count, bool suppress_error) { - if (update_array_create(&update->root_array, old_data, old_data_end, - part_count) != 0) + if (update_array_create(&update->root_array, header, old_data, + old_data_end, part_count) != 0) return -1; struct update_op *op = update->ops; struct update_op *ops_end = op + update->op_count; @@ -276,11 +277,13 @@ tuple_update_execute(const char *expr,const char *expr_end, { struct tuple_update update; update_init(&update, index_base); + const char *header = old_data; uint32_t field_count = mp_decode_array(&old_data); if (update_read_ops(&update, expr, expr_end, dict, field_count) != 0) return NULL; - if (update_do_ops(&update, old_data, old_data_end, field_count)) + if (update_do_ops(&update, header, old_data, old_data_end, + field_count) != 0) return NULL; if (column_mask) *column_mask = update.column_mask; @@ -296,12 +299,13 @@ tuple_upsert_execute(const char *expr,const char *expr_end, { struct tuple_update update; update_init(&update, index_base); + const char *header = old_data; uint32_t field_count = mp_decode_array(&old_data); if (update_read_ops(&update, expr, expr_end, dict, field_count) != 0) return NULL; - if (upsert_do_ops(&update, old_data, old_data_end, field_count, - suppress_error)) + if (upsert_do_ops(&update, header, old_data, old_data_end, field_count, + suppress_error) != 0) return NULL; if (column_mask) *column_mask = update.column_mask; diff --git a/src/box/update/update_array.c b/src/box/update/update_array.c index 985d555af..5b834b644 100644 --- a/src/box/update/update_array.c +++ b/src/box/update/update_array.c @@ -143,12 +143,13 @@ update_array_extract_item(struct update_field *field, struct update_op *op) } int -update_array_create(struct update_field *field, const char *data, - const char *data_end, uint32_t field_count) +update_array_create(struct update_field *field, const char *header, + const char *data, const char *data_end, + uint32_t field_count) { field->type = UPDATE_ARRAY; - field->data = data; - field->size = data_end - data; + field->data = header; + field->size = data_end - header; field->array.rope = rope_new(&fiber()->gc); if (field->array.rope == NULL) return -1; diff --git a/src/box/update/update_field.h b/src/box/update/update_field.h index b03c7479f..35ec85238 100644 --- a/src/box/update/update_field.h +++ b/src/box/update/update_field.h @@ -303,6 +303,7 @@ update_##type##_store(struct update_field *field, char *out, char *out_end); /** * Initialize @a field as an array to update. * @param[out] field Field to initialize. + * @param header Header of the MessagePack array @a data. * @param data MessagePack data of the array to update. * @param data_end End of @a data. * @param field_count Field count in @data. @@ -311,8 +312,9 @@ update_##type##_store(struct update_field *field, char *out, char *out_end); * @retval -1 Error. */ int -update_array_create(struct update_field *field, const char *data, - const char *data_end, uint32_t field_count); +update_array_create(struct update_field *field, const char *header, + const char *data, const char *data_end, + uint32_t field_count); OP_DECL_GENERIC(array) -- 2.20.1 (Apple Git-117)