[Tarantool-patches] [PATCH v3 2/2] vinyl: remove squash procedures from source code

Nikita Pettik korablev at tarantool.org
Sat Oct 3 16:28:51 MSK 2020


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



More information about the Tarantool-patches mailing list