diff options
author | Matthias Radestock <matthias@rabbitmq.com> | 2010-11-17 16:30:37 +0000 |
---|---|---|
committer | Matthias Radestock <matthias@rabbitmq.com> | 2010-11-17 16:30:37 +0000 |
commit | af1f6be9950a71dd5682dc604e87f9db881fffea (patch) | |
tree | 22f70ec4c5fbf8435c76c1e173c5a44b74d83abd | |
parent | 2c566713c29f406d90d336861c4056470f2ca97c (diff) | |
download | rabbitmq-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.erl | 15 |
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}) -> |