summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmile Joubert <emile@rabbitmq.com>2012-08-23 15:59:45 +0100
committerEmile Joubert <emile@rabbitmq.com>2012-08-23 15:59:45 +0100
commitdefdb24b336394e6806149be5580b381143cff3e (patch)
treefc9858658a07eb3d4b2fd434e70e1c74470cf3d7
parent2b7a86181289078a8a3b407d8df876f111051fec (diff)
downloadrabbitmq-server-defdb24b336394e6806149be5580b381143cff3e.tar.gz
Compile regular expressions that will be matched multiple times
-rw-r--r--src/rabbit_policy.erl30
1 files changed, 23 insertions, 7 deletions
diff --git a/src/rabbit_policy.erl b/src/rabbit_policy.erl
index 3ed0734b..3400a7d5 100644
--- a/src/rabbit_policy.erl
+++ b/src/rabbit_policy.erl
@@ -81,11 +81,12 @@ notify_clear(VHost, <<"policy">>, _Name) ->
%%----------------------------------------------------------------------------
list(VHost) ->
- [[{<<"name">>, pget(key, P)} | pget(value, P)]
- || P <- rabbit_runtime_parameters:list(VHost, <<"policy">>)].
+ lists:sort(fun sort_pred/2,
+ [[{<<"name">>, pget(key, P)} | pget(value, P)]
+ || P <- rabbit_runtime_parameters:list(VHost, <<"policy">>)]).
update_policies(VHost) ->
- Policies = list(VHost),
+ Policies = add_compile(list(VHost)),
{Xs, Qs} = rabbit_misc:execute_mnesia_transaction(
fun() ->
{[update_exchange(X, Policies) ||
@@ -98,7 +99,7 @@ update_policies(VHost) ->
ok.
update_exchange(X = #exchange{name = XName, policy = OldPolicy}, Policies) ->
- NewPolicy = match(XName, Policies),
+ NewPolicy = strip_compile(match(XName, Policies)),
case NewPolicy of
OldPolicy -> no_change;
_ -> rabbit_exchange:update(
@@ -107,7 +108,7 @@ update_exchange(X = #exchange{name = XName, policy = OldPolicy}, Policies) ->
end.
update_queue(Q = #amqqueue{name = QName, policy = OldPolicy}, Policies) ->
- NewPolicy = match(QName, Policies),
+ NewPolicy = strip_compile(match(QName, Policies)),
case NewPolicy of
OldPolicy -> no_change;
_ -> rabbit_amqqueue:update(
@@ -123,19 +124,34 @@ notify({Q1 = #amqqueue{}, Q2 = #amqqueue{}}) ->
rabbit_amqqueue:policy_changed(Q1, Q2).
match(Name, Policies) ->
- case lists:sort(fun sort_pred/2, [P || P <- Policies, matches(Name, P)]) of
+ case lists:filter(fun (P) -> matches(Name, P) end, Policies) of
[] -> undefined;
[Policy | _Rest] -> Policy
end.
matches(#resource{name = Name}, Policy) ->
case re:run(binary_to_list(Name),
- binary_to_list(pget(<<"pattern">>, Policy)),
+ pattern_pref(Policy),
[{capture, none}]) of
nomatch -> false;
match -> true
end.
+add_compile(Policies) ->
+ [ begin
+ {ok, MP} = re:compile(binary_to_list(pget(<<"pattern">>, Policy))),
+ [{<<"compiled">>, MP} | Policy]
+ end || Policy <- Policies ].
+
+strip_compile(undefined) -> undefined;
+strip_compile(Policy) -> proplists:delete(<<"compiled">>, Policy).
+
+pattern_pref(Policy) ->
+ case pget(<<"compiled">>, Policy) of
+ undefined -> binary_to_list(pget(<<"pattern">>, Policy));
+ Compiled -> Compiled
+ end.
+
sort_pred(A, B) ->
pget(<<"priority">>, A) >= pget(<<"priority">>, B).