summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Radestock <matthias@rabbitmq.com>2010-11-17 16:30:37 +0000
committerMatthias Radestock <matthias@rabbitmq.com>2010-11-17 16:30:37 +0000
commitaf1f6be9950a71dd5682dc604e87f9db881fffea (patch)
tree22f70ec4c5fbf8435c76c1e173c5a44b74d83abd
parent2c566713c29f406d90d336861c4056470f2ca97c (diff)
downloadrabbitmq-server-bug23505.tar.gz
some routing optimisationbug23505
- handle the very common "message goes through single exchange" case specially - use a gb_set in all other cases - it performs much better than a set for smaller sets, and not too badly for very large sets either.
-rw-r--r--src/rabbit_exchange.erl15
1 files changed, 12 insertions, 3 deletions
diff --git a/src/rabbit_exchange.erl b/src/rabbit_exchange.erl
index 61a24388..4c0f341f 100644
--- a/src/rabbit_exchange.erl
+++ b/src/rabbit_exchange.erl
@@ -228,7 +228,7 @@ info_all(VHostPath, Items) -> map(VHostPath, fun (X) -> info(X, Items) end).
publish(X = #exchange{name = XName}, Delivery) ->
rabbit_router:deliver(
- route(Delivery, {queue:from_list([X]), sets:from_list([XName]), []}),
+ route(Delivery, {queue:from_list([X]), XName, []}),
Delivery).
route(Delivery, {WorkList, SeenXs, QNames}) ->
@@ -252,13 +252,22 @@ process_alternate(_X, Results) ->
Results.
process_route(#resource{kind = exchange} = XName,
+ {_WorkList, XName, _QNames} = Acc) ->
+ Acc;
+process_route(#resource{kind = exchange} = XName,
+ {WorkList, #resource{kind = exchange} = SeenX, QNames}) ->
+ {case lookup(XName) of
+ {ok, X} -> queue:in(X, WorkList);
+ {error, not_found} -> WorkList
+ end, gb_sets:from_list([SeenX, XName]), QNames};
+process_route(#resource{kind = exchange} = XName,
{WorkList, SeenXs, QNames} = Acc) ->
- case sets:is_element(XName, SeenXs) of
+ case gb_sets:is_element(XName, SeenXs) of
true -> Acc;
false -> {case lookup(XName) of
{ok, X} -> queue:in(X, WorkList);
{error, not_found} -> WorkList
- end, sets:add_element(XName, SeenXs), QNames}
+ end, gb_sets:add_element(XName, SeenXs), QNames}
end;
process_route(#resource{kind = queue} = QName,
{WorkList, SeenXs, QNames}) ->