From: Nikita Pettik <korablev@tarantool.org> To: tarantool-patches@dev.tarantool.org Cc: v.shpilevoy@tarantool.org Subject: [Tarantool-patches] [PATCH v3 2/2] vinyl: remove squash procedures from source code Date: Sat, 3 Oct 2020 16:28:51 +0300 [thread overview] Message-ID: <fc1cc4a44818df3546747a15fc77a4d115e9ede1.1601729099.git.korablev@tarantool.org> (raw) In-Reply-To: <cover.1601729099.git.korablev@tarantool.org> In-Reply-To: <cover.1601729099.git.korablev@tarantool.org> After previous commit, there's no need in these functions. However, someday we may want to reconsider it squash optimization and make it work without breaking upsert associativity rule. So to not lost initial squash implementation, let's put its removal in a separate patch. Follow-up #5107 --- src/box/xrow_update.c | 144 ------------------------------------------ src/box/xrow_update.h | 14 ---- 2 files changed, 158 deletions(-) diff --git a/src/box/xrow_update.c b/src/box/xrow_update.c index 833975f03..cba182ab2 100644 --- a/src/box/xrow_update.c +++ b/src/box/xrow_update.c @@ -415,147 +415,3 @@ xrow_upsert_execute(const char *expr,const char *expr_end, return xrow_update_finish(&update, format, p_tuple_len); } - -const char * -xrow_upsert_squash(const char *expr1, const char *expr1_end, - const char *expr2, const char *expr2_end, - struct tuple_format *format, size_t *result_size) -{ - const char *expr[2] = {expr1, expr2}; - const char *expr_end[2] = {expr1_end, expr2_end}; - struct xrow_update update[2]; - struct tuple_dictionary *dict = format->dict; - for (int j = 0; j < 2; j++) { - xrow_update_init(&update[j], 0); - if (xrow_update_read_ops(&update[j], expr[j], expr_end[j], - dict, 0) != 0) - return NULL; - mp_decode_array(&expr[j]); - int32_t prev_field_no = -1; - for (uint32_t i = 0; i < update[j].op_count; i++) { - struct xrow_update_op *op = &update[j].ops[i]; - if (op->opcode != '+' && op->opcode != '-' && - op->opcode != '=') - return NULL; - /* - * Not terminal operation means, that the - * update is not flat, and squash would - * need to build a tree of operations to - * find matches. That is too complex, - * squash is skipped. - */ - if (!xrow_update_op_is_term(op)) - return NULL; - if (op->field_no <= prev_field_no) - return NULL; - prev_field_no = op->field_no; - } - } - size_t possible_size = expr1_end - expr1 + expr2_end - expr2; - const uint32_t space_for_arr_tag = 5; - char *buf = (char *) region_alloc(&fiber()->gc, - possible_size + space_for_arr_tag); - if (buf == NULL) { - diag_set(OutOfMemory, possible_size + space_for_arr_tag, - "region_alloc", "buf"); - return NULL; - } - /* reserve some space for mp array header */ - char *res_ops = buf + space_for_arr_tag; - uint32_t res_count = 0; /* number of resulting operations */ - - uint32_t op_count[2] = {update[0].op_count, update[1].op_count}; - uint32_t op_no[2] = {0, 0}; - struct json_tree *format_tree = &format->fields; - struct json_token *root = &format_tree->root; - struct json_token token; - token.type = JSON_TOKEN_NUM; - while (op_no[0] < op_count[0] || op_no[1] < op_count[1]) { - res_count++; - struct xrow_update_op *op[2] = {update[0].ops + op_no[0], - update[1].ops + op_no[1]}; - /* - * from: - * 0 - take op from first update, - * 1 - take op from second update, - * 2 - merge both ops - */ - uint32_t from; - uint32_t has[2] = {op_no[0] < op_count[0], op_no[1] < op_count[1]}; - assert(has[0] || has[1]); - if (has[0] && has[1]) { - from = op[0]->field_no < op[1]->field_no ? 0 : - op[0]->field_no > op[1]->field_no ? 1 : 2; - } else { - assert(has[0] != has[1]); - from = has[1]; - } - if (from == 2 && op[1]->opcode == '=') { - /* - * If an operation from the second upsert is '=' - * it is just overwrites any op from the first upsert. - * So we just skip op from the first upsert and - * copy op from the second - */ - mp_next(&expr[0]); - op_no[0]++; - from = 1; - } - if (from < 2) { - /* take op from one of upserts */ - const char *copy = expr[from]; - mp_next(&expr[from]); - size_t copy_size = expr[from] - copy; - memcpy(res_ops, copy, copy_size); - res_ops += copy_size; - op_no[from]++; - continue; - } - /* merge: apply second '+' or '-' */ - assert(op[1]->opcode == '+' || op[1]->opcode == '-'); - if (op[0]->opcode == '-') { - op[0]->opcode = '+'; - int96_invert(&op[0]->arg.arith.int96); - } - struct xrow_update_arg_arith arith; - /* - * If we apply + or - on top of the set operation ('='), - * then resulting operation is {'=', op1.val + op2.val}. - * To continue processing arithmetic operation we should - * firstly extract value from set operation holder. - */ - if (op[0]->opcode == '=') { - if (xrow_mp_read_arg_arith(op[0], &op[0]->arg.set.value, - &arith) != 0) - return NULL; - } else { - arith = op[0]->arg.arith; - } - struct xrow_update_op res; - if (xrow_update_arith_make(op[1], arith, - &res.arg.arith) != 0) - return NULL; - res_ops = mp_encode_array(res_ops, 3); - res_ops = mp_encode_str(res_ops, - (const char *)&op[0]->opcode, 1); - token.num = op[0]->field_no; - res_ops = mp_encode_uint(res_ops, token.num + - update[0].index_base); - struct json_token *this_node = - json_tree_lookup(format_tree, root, &token); - xrow_update_op_store_arith(&res, format_tree, this_node, NULL, - res_ops); - res_ops += xrow_update_arg_arith_sizeof(&res.arg.arith); - mp_next(&expr[0]); - mp_next(&expr[1]); - op_no[0]++; - op_no[1]++; - } - assert(op_no[0] == op_count[0] && op_no[1] == op_count[1]); - assert(expr[0] == expr_end[0] && expr[1] == expr_end[1]); - char *arr_start = buf + space_for_arr_tag - - mp_sizeof_array(res_count); - mp_encode_array(arr_start, res_count); - *result_size = res_ops - arr_start; - return arr_start; -} diff --git a/src/box/xrow_update.h b/src/box/xrow_update.h index ba4abb1b0..64b4cd034 100644 --- a/src/box/xrow_update.h +++ b/src/box/xrow_update.h @@ -63,20 +63,6 @@ xrow_upsert_execute(const char *expr, const char *expr_end, int index_base, bool suppress_error, uint64_t *column_mask); -/** - * Try to merge two update/upsert expressions to an equivalent one. - * Due to optimization reasons resulting expression - * is located inside a bigger allocation. There also some hidden - * internal allocations are made in this function. - * Thus the only allocator that can be used in this function - * is region allocator. - * If it isn't possible to merge expressions NULL is returned. - */ -const char * -xrow_upsert_squash(const char *expr1, const char *expr1_end, - const char *expr2, const char *expr2_end, - struct tuple_format *format, size_t *result_size); - #if defined(__cplusplus) } /* extern "C" */ #endif /* defined(__cplusplus) */ -- 2.17.1
next prev parent reply other threads:[~2020-10-03 13:28 UTC|newest] Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-10-03 13:28 [Tarantool-patches] [PATCH v3 0/2] vinyl: rework upsert operation Nikita Pettik 2020-10-03 13:28 ` [Tarantool-patches] [PATCH v3 1/2] " Nikita Pettik 2020-10-06 22:12 ` Vladislav Shpilevoy 2020-10-09 15:06 ` Nikita Pettik 2020-10-13 19:00 ` Aleksandr Lyapunov 2020-10-14 0:15 ` Nikita Pettik 2020-10-14 8:58 ` Aleksandr Lyapunov 2020-10-14 10:42 ` Nikita Pettik 2020-10-14 11:47 ` Aleksandr Lyapunov 2020-10-15 0:36 ` Nikita Pettik 2020-10-03 13:28 ` Nikita Pettik [this message] 2020-10-03 13:52 ` [Tarantool-patches] [PATCH v3 0/2] " Nikita Pettik 2020-10-06 22:12 ` Vladislav Shpilevoy 2020-10-09 15:10 ` Nikita Pettik 2020-10-11 15:35 ` Vladislav Shpilevoy 2020-10-11 15:35 ` Vladislav Shpilevoy 2020-10-13 10:18 ` Nikita Pettik 2020-10-14 23:44 ` Vladislav Shpilevoy 2020-10-15 1:42 ` Nikita Pettik
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=fc1cc4a44818df3546747a15fc77a4d115e9ede1.1601729099.git.korablev@tarantool.org \ --to=korablev@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v3 2/2] vinyl: remove squash procedures from source code' \ /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