2
0
Эх сурвалжийг харах

dialplan: improve performance by reusing PCRE structure

Lucian Balaceanu 2 сар өмнө
parent
commit
6d1f59df69

+ 18 - 18
src/modules/dialplan/dp_repl.c

@@ -409,7 +409,7 @@ int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule,
 	int repl_nb, offset, match_nb, rc, cap_cnt;
 	int repl_nb, offset, match_nb, rc, cap_cnt;
 	struct replace_with token;
 	struct replace_with token;
 	struct subst_expr *repl_comp;
 	struct subst_expr *repl_comp;
-	pcre2_match_data *pcre_md = NULL;
+	static pcre2_match_data *pcre_md = NULL;
 	str match;
 	str match;
 	pv_value_t sv;
 	pv_value_t sv;
 	str *uri;
 	str *uri;
@@ -427,6 +427,14 @@ int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule,
 		return 0;
 		return 0;
 	}
 	}
 
 
+	if(pcre_md == NULL) {
+		pcre_md = pcre2_match_data_create(MAX_REPLACE_WITH, NULL);
+		if(pcre_md == NULL) {
+			LM_ERR("failed to allocate pcre2_match_data\n");
+			return -1;
+		}
+	}
+
 	if(subst_comp) {
 	if(subst_comp) {
 		/*just in case something went wrong at load time*/
 		/*just in case something went wrong at load time*/
 		rc = pcre2_pattern_info(subst_comp, PCRE2_INFO_CAPTURECOUNT, &cap_cnt);
 		rc = pcre2_pattern_info(subst_comp, PCRE2_INFO_CAPTURECOUNT, &cap_cnt);
@@ -446,7 +454,6 @@ int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule,
 		}
 		}
 
 
 		/*search for the pattern from the compiled subst_exp*/
 		/*search for the pattern from the compiled subst_exp*/
-		pcre_md = pcre2_match_data_create_from_pattern(subst_comp, NULL);
 		if(pcre2_match(subst_comp, (PCRE2_SPTR)instr->s, (PCRE2_SIZE)instr->len,
 		if(pcre2_match(subst_comp, (PCRE2_SPTR)instr->s, (PCRE2_SIZE)instr->len,
 				   0, 0, pcre_md, NULL)
 				   0, 0, pcre_md, NULL)
 				<= 0) {
 				<= 0) {
@@ -454,8 +461,6 @@ int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule,
 				   "the match_exp %.*s but not the subst_exp %.*s!\n",
 				   "the match_exp %.*s but not the subst_exp %.*s!\n",
 					instr->len, instr->s, rule->match_exp.len,
 					instr->len, instr->s, rule->match_exp.len,
 					rule->match_exp.s, rule->subst_exp.len, rule->subst_exp.s);
 					rule->match_exp.s, rule->subst_exp.len, rule->subst_exp.s);
-			if(pcre_md)
-				pcre2_match_data_free(pcre_md);
 			return -1;
 			return -1;
 		}
 		}
 		ovector = pcre2_get_ovector_pointer(pcre_md);
 		ovector = pcre2_get_ovector_pointer(pcre_md);
@@ -472,8 +477,6 @@ int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule,
 		memcpy(result->s, repl_comp->replacement.s, repl_comp->replacement.len);
 		memcpy(result->s, repl_comp->replacement.s, repl_comp->replacement.len);
 		result->len = repl_comp->replacement.len;
 		result->len = repl_comp->replacement.len;
 		result->s[result->len] = '\0';
 		result->s[result->len] = '\0';
-		if(pcre_md)
-			pcre2_match_data_free(pcre_md);
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -582,15 +585,11 @@ int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule,
 	}
 	}
 
 
 	result->s[result->len] = '\0';
 	result->s[result->len] = '\0';
-	if(pcre_md)
-		pcre2_match_data_free(pcre_md);
 	return 0;
 	return 0;
 
 
 error:
 error:
 	result->s = 0;
 	result->s = 0;
 	result->len = 0;
 	result->len = 0;
-	if(pcre_md)
-		pcre2_match_data_free(pcre_md);
 	return -1;
 	return -1;
 }
 }
 
 
@@ -599,7 +598,7 @@ static char dp_attrs_buf[DP_MAX_ATTRS_LEN + 1];
 int dp_translate_helper(
 int dp_translate_helper(
 		sip_msg_t *msg, str *input, str *output, dpl_id_p idp, str *attrs)
 		sip_msg_t *msg, str *input, str *output, dpl_id_p idp, str *attrs)
 {
 {
-	pcre2_match_data *pcre_md = NULL;
+	static pcre2_match_data *pcre_md = NULL;
 	dpl_node_p rulep;
 	dpl_node_p rulep;
 	dpl_index_p indexp;
 	dpl_index_p indexp;
 	int user_len, rez;
 	int user_len, rez;
@@ -622,6 +621,14 @@ int dp_translate_helper(
 		return -1;
 		return -1;
 	}
 	}
 
 
+	if(pcre_md == NULL) {
+		pcre_md = pcre2_match_data_create(MAX_REPLACE_WITH, NULL);
+		if(pcre_md == NULL) {
+			LM_ERR("failed to allocate pcre2_match_data\n");
+			return -1;
+		}
+	}
+
 search_rule:
 search_rule:
 	for(rulep = indexp->first_rule; rulep != NULL; rulep = rulep->next) {
 	for(rulep = indexp->first_rule; rulep != NULL; rulep = rulep->next) {
 		switch(rulep->matchop) {
 		switch(rulep->matchop) {
@@ -640,8 +647,6 @@ search_rule:
 					rez = -1;
 					rez = -1;
 					do {
 					do {
 						if(rez < 0) {
 						if(rez < 0) {
-							pcre_md = pcre2_match_data_create_from_pattern(
-									re_list->re, NULL);
 							rez = pcre2_match(re_list->re, (PCRE2_SPTR)input->s,
 							rez = pcre2_match(re_list->re, (PCRE2_SPTR)input->s,
 									(PCRE2_SIZE)input->len, 0, 0, pcre_md,
 									(PCRE2_SIZE)input->len, 0, 0, pcre_md,
 									NULL);
 									NULL);
@@ -651,18 +656,13 @@ search_rule:
 							LM_DBG("match check skipped: [%.*s] %d\n",
 							LM_DBG("match check skipped: [%.*s] %d\n",
 									re_list->expr.len, re_list->expr.s, rez);
 									re_list->expr.len, re_list->expr.s, rez);
 						rt = re_list->next;
 						rt = re_list->next;
-						if(pcre_md)
-							pcre2_match_data_free(pcre_md);
 						pcre2_code_free(re_list->re);
 						pcre2_code_free(re_list->re);
 						pkg_free(re_list);
 						pkg_free(re_list);
 						re_list = rt;
 						re_list = rt;
 					} while(re_list);
 					} while(re_list);
 				} else {
 				} else {
-					pcre_md = pcre2_match_data_create_from_pattern(
-							rulep->match_comp, NULL);
 					rez = pcre2_match(rulep->match_comp, (PCRE2_SPTR)input->s,
 					rez = pcre2_match(rulep->match_comp, (PCRE2_SPTR)input->s,
 							(PCRE2_SIZE)input->len, 0, 0, pcre_md, 0);
 							(PCRE2_SIZE)input->len, 0, 0, pcre_md, 0);
-					pcre2_match_data_free(pcre_md);
 				}
 				}
 				break;
 				break;