From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: tarantool-patches@dev.tarantool.org, kostja.osipov@gmail.com, imun@tarantool.org, korablev@tarantool.org Subject: [Tarantool-patches] [PATCH v2 3/4] tuple: allow xrow_update sizeof reserve more memory Date: Tue, 4 Feb 2020 23:53:46 +0100 [thread overview] Message-ID: <c3b87990d01b59991834dca160e201851d3a3084.1580856722.git.v.shpilevoy@tarantool.org> (raw) In-Reply-To: <cover.1580856721.git.v.shpilevoy@tarantool.org> Currently xrow_update sizeof + store are used to calculate the result tuple's size, preallocate it as a monolithic memory block, and save the update tree into it. Sizeof was expected to return the exact memory size needed for the tuple. But this is not useful when result size of a field depends on its format type, and therefore on its position in the tuple. Because in that case sizeof would need to care about tuple format, and walk format tree just like store does now. Or it would be needed to save the found json tree nodes into struct xrow_update_op during sizeof calculation. All of this would make sizeof code more complex. The patch makes it possible for sizeof to return the maximal needed size. So, for example, a floating point field size now returns size needed for encoding of a double. And then store can either encode double or float. Follow-up #4701 --- src/box/xrow_update.c | 2 +- src/box/xrow_update_bar.c | 5 ++--- src/box/xrow_update_field.c | 37 ++++++++++++++++++++++--------------- src/box/xrow_update_field.h | 4 ++-- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/box/xrow_update.c b/src/box/xrow_update.c index ac8c9d303..63f7bc3da 100644 --- a/src/box/xrow_update.c +++ b/src/box/xrow_update.c @@ -357,7 +357,7 @@ xrow_update_finish(struct xrow_update *update, struct tuple_format *format, *p_tuple_len = xrow_update_array_store(&update->root, &format->fields, &format->fields.root, buffer, buffer + tuple_len); - assert(*p_tuple_len == tuple_len); + assert(*p_tuple_len <= tuple_len); return buffer; } diff --git a/src/box/xrow_update_bar.c b/src/box/xrow_update_bar.c index b4a98978a..0033f0044 100644 --- a/src/box/xrow_update_bar.c +++ b/src/box/xrow_update_bar.c @@ -446,9 +446,8 @@ xrow_update_bar_store(struct xrow_update_field *field, memcpy(out, field->data, before_point); out += before_point; - op->meta->store(op, format_tree, this_node, field->bar.point, - out); - out += op->new_field_len; + out += op->meta->store(op, format_tree, this_node, + field->bar.point, out); memcpy(out, point_end, after_point); return out + after_point - out_saved; } diff --git a/src/box/xrow_update_field.c b/src/box/xrow_update_field.c index 42a3ba50a..d431c22f8 100644 --- a/src/box/xrow_update_field.c +++ b/src/box/xrow_update_field.c @@ -132,7 +132,6 @@ xrow_update_field_store(struct xrow_update_field *field, struct json_token *this_node, char *out, char *out_end) { struct xrow_update_op *op; - uint32_t size; switch(field->type) { case XUPDATE_NOP: assert(out_end - out >= field->size); @@ -140,10 +139,9 @@ xrow_update_field_store(struct xrow_update_field *field, return field->size; case XUPDATE_SCALAR: op = field->scalar.op; - size = op->new_field_len; - assert(out_end - out >= size); - op->meta->store(op, format_tree, this_node, field->data, out); - return size; + assert(out_end - out >= op->new_field_len); + return op->meta->store(op, format_tree, this_node, field->data, + out); case XUPDATE_ARRAY: return xrow_update_array_store(field, format_tree, this_node, out, out_end); @@ -516,7 +514,7 @@ xrow_update_op_do_splice(struct xrow_update_op *op, const char *old) /* {{{ store_op */ -static void +static uint32_t xrow_update_op_store_set(struct xrow_update_op *op, struct json_tree *format_tree, struct json_token *this_node, const char *in, @@ -526,9 +524,10 @@ xrow_update_op_store_set(struct xrow_update_op *op, (void) this_node; (void) in; memcpy(out, op->arg.set.value, op->arg.set.length); + return op->arg.set.length; } -void +uint32_t xrow_update_op_store_arith(struct xrow_update_op *op, struct json_tree *format_tree, struct json_token *this_node, const char *in, @@ -537,30 +536,34 @@ xrow_update_op_store_arith(struct xrow_update_op *op, (void) format_tree; (void) this_node; (void) in; + char *begin = out; struct xrow_update_arg_arith *arg = &op->arg.arith; switch (arg->type) { case XUPDATE_TYPE_INT: if (int96_is_uint64(&arg->int96)) { - mp_encode_uint(out, int96_extract_uint64(&arg->int96)); + out = mp_encode_uint( + out, int96_extract_uint64(&arg->int96)); } else { assert(int96_is_neg_int64(&arg->int96)); - mp_encode_int(out, int96_extract_neg_int64(&arg->int96)); + out = mp_encode_int( + out, int96_extract_neg_int64( &arg->int96)); } break; case XUPDATE_TYPE_DOUBLE: - mp_encode_double(out, arg->dbl); + out = mp_encode_double(out, arg->dbl); break; case XUPDATE_TYPE_FLOAT: - mp_encode_float(out, arg->flt); + out = mp_encode_float(out, arg->flt); break; default: assert(arg->type == XUPDATE_TYPE_DECIMAL); - mp_encode_decimal(out, &arg->dec); + out = mp_encode_decimal(out, &arg->dec); break; } + return out - begin; } -static void +static uint32_t xrow_update_op_store_bit(struct xrow_update_op *op, struct json_tree *format_tree, struct json_token *this_node, const char *in, @@ -569,10 +572,11 @@ xrow_update_op_store_bit(struct xrow_update_op *op, (void) format_tree; (void) this_node; (void) in; - mp_encode_uint(out, op->arg.bit.val); + char *end = mp_encode_uint(out, op->arg.bit.val); + return end - out; } -static void +static uint32_t xrow_update_op_store_splice(struct xrow_update_op *op, struct json_tree *format_tree, struct json_token *this_node, const char *in, @@ -583,6 +587,7 @@ xrow_update_op_store_splice(struct xrow_update_op *op, struct xrow_update_arg_splice *arg = &op->arg.splice; uint32_t new_str_len = arg->offset + arg->paste_length + arg->tail_length; + char *begin = out; (void) mp_decode_strl(&in); out = mp_encode_strl(out, new_str_len); /* Copy field head. */ @@ -593,6 +598,8 @@ xrow_update_op_store_splice(struct xrow_update_op *op, out = out + arg->paste_length; /* Copy tail. */ memcpy(out, in + arg->tail_offset, arg->tail_length); + out = out + arg->tail_length; + return out - begin; } /* }}} store_op */ diff --git a/src/box/xrow_update_field.h b/src/box/xrow_update_field.h index 782cb5d3f..5a8a79881 100644 --- a/src/box/xrow_update_field.h +++ b/src/box/xrow_update_field.h @@ -151,7 +151,7 @@ typedef int (*xrow_update_op_do_f)(struct xrow_update_op *op, struct xrow_update_field *field); -typedef void +typedef uint32_t (*xrow_update_op_store_f)(struct xrow_update_op *op, struct json_tree *format_tree, struct json_token *this_node, const char *in, @@ -711,7 +711,7 @@ xrow_update_arith_make(struct xrow_update_op *op, struct xrow_update_arg_arith arg, struct xrow_update_arg_arith *ret); -void +uint32_t xrow_update_op_store_arith(struct xrow_update_op *op, struct json_tree *format_tree, struct json_token *this_node, const char *in, -- 2.21.1 (Apple Git-122.3)
next prev parent reply other threads:[~2020-02-04 22:53 UTC|newest] Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-02-04 22:53 [Tarantool-patches] [PATCH v2 0/4] Don't truncate float in update Vladislav Shpilevoy 2020-02-04 22:53 ` [Tarantool-patches] [PATCH v2 1/4] tuple: don't truncate float in :update() Vladislav Shpilevoy 2020-02-10 14:41 ` Nikita Pettik 2020-02-10 21:18 ` Vladislav Shpilevoy 2020-02-19 21:36 ` Nikita Pettik 2020-02-04 22:53 ` [Tarantool-patches] [PATCH v2 2/4] tuple: pass tuple format to xrow_update_*_store() Vladislav Shpilevoy 2020-02-10 16:51 ` Nikita Pettik 2020-02-10 21:18 ` Vladislav Shpilevoy 2020-02-04 22:53 ` Vladislav Shpilevoy [this message] 2020-02-10 16:05 ` [Tarantool-patches] [PATCH v2 3/4] tuple: allow xrow_update sizeof reserve more memory Nikita Pettik 2020-02-04 22:53 ` [Tarantool-patches] [PATCH v2 4/4] tuple: use field type in update of a float/double Vladislav Shpilevoy 2020-02-10 16:16 ` Nikita Pettik 2020-02-10 21:18 ` Vladislav Shpilevoy 2020-02-05 11:09 ` [Tarantool-patches] [PATCH v2 0/4] Don't truncate float in update Konstantin Osipov 2020-02-05 22:11 ` Vladislav Shpilevoy 2020-02-20 6:15 ` Kirill Yukhin 2020-02-20 13:27 ` Nikita Pettik 2020-02-20 20:30 ` 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=c3b87990d01b59991834dca160e201851d3a3084.1580856722.git.v.shpilevoy@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=imun@tarantool.org \ --cc=korablev@tarantool.org \ --cc=kostja.osipov@gmail.com \ --cc=tarantool-patches@dev.tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v2 3/4] tuple: allow xrow_update sizeof reserve more memory' \ /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