Expression parser: Optimize another concatenation

case by using iteration instead of recursion.

We have a relatively small recursion limit of
about 10 operations. This is a compilation
limit (a define). It can be hit if many expr
vars or function calls are concatenated.

The new optimization is very similar to the
existing one, which optimizes consecutive
concatenations in node2 of the tree. The new
one optimizes consecutive concatenations in
node 1.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1657685 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Rainer Jung
2015-02-05 20:33:59 +00:00
parent c558110372
commit 7439a429d6

View File

@ -103,7 +103,8 @@ static const char *ap_expr_eval_word(ap_expr_eval_ctx_t *ctx,
node->node_arg2);
break;
case op_Concat:
if (((ap_expr_t *)node->node_arg2)->node_op != op_Concat) {
if (((ap_expr_t *)node->node_arg2)->node_op != op_Concat &&
((ap_expr_t *)node->node_arg1)->node_op != op_Concat) {
const char *s1 = ap_expr_eval_word(ctx, node->node_arg1);
const char *s2 = ap_expr_eval_word(ctx, node->node_arg2);
if (!*s1)
@ -113,6 +114,30 @@ static const char *ap_expr_eval_word(ap_expr_eval_ctx_t *ctx,
else
result = apr_pstrcat(ctx->p, s1, s2, NULL);
}
else if (((ap_expr_t *)node->node_arg1)->node_op == op_Concat) {
const ap_expr_t *nodep = node;
int n;
int i = 1;
struct iovec *vec;
do {
nodep = nodep->node_arg1;
i++;
} while (nodep->node_op == op_Concat);
vec = apr_palloc(ctx->p, i * sizeof(struct iovec));
n = i;
nodep = node;
i--;
do {
vec[i].iov_base = (void *)ap_expr_eval_word(ctx,
nodep->node_arg2);
vec[i].iov_len = strlen(vec[i].iov_base);
i--;
nodep = nodep->node_arg1;
} while (nodep->node_op == op_Concat);
vec[i].iov_base = (void *)ap_expr_eval_word(ctx, nodep);
vec[i].iov_len = strlen(vec[i].iov_base);
result = apr_pstrcatv(ctx->p, vec, n, NULL);
}
else {
const ap_expr_t *nodep = node;
int i = 1;