diff options
author | Rob Harrop <rob@rabbitmq.com> | 2011-06-07 10:02:05 +0100 |
---|---|---|
committer | Rob Harrop <rob@rabbitmq.com> | 2011-06-07 10:02:05 +0100 |
commit | f6ee62606afbeabcf53f11b398f45d0972c0fc3b (patch) | |
tree | 0ba04163ab21d3ed3270dc2aee0dae7fb3f39276 | |
parent | 3af990393f20a4e2ae23d4db8c41bb34d6e990b3 (diff) | |
parent | bc0233a9aa74bf30c2cf65ae1d90ca4bee28f208 (diff) | |
download | rabbitmq-server-f6ee62606afbeabcf53f11b398f45d0972c0fc3b.tar.gz |
Merge bug24151 into default
-rw-r--r-- | src/rabbit_router.erl | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/src/rabbit_router.erl b/src/rabbit_router.erl index f6a1c92f..8f166672 100644 --- a/src/rabbit_router.erl +++ b/src/rabbit_router.erl @@ -84,21 +84,18 @@ match_bindings(SrcName, Match) -> mnesia:async_dirty(fun qlc:e/1, [Query]). match_routing_key(SrcName, [RoutingKey]) -> - MatchHead = #route{binding = #binding{source = SrcName, + find_routes(#route{binding = #binding{source = SrcName, destination = '$1', key = RoutingKey, _ = '_'}}, - mnesia:dirty_select(rabbit_route, [{MatchHead, [], ['$1']}]); + []); match_routing_key(SrcName, [_|_] = RoutingKeys) -> - Condition = list_to_tuple(['orelse' | [{'=:=', '$2', RKey} || - RKey <- RoutingKeys]]), - MatchHead = #route{binding = #binding{source = SrcName, + find_routes(#route{binding = #binding{source = SrcName, destination = '$1', key = '$2', _ = '_'}}, - mnesia:dirty_select(rabbit_route, [{MatchHead, [Condition], ['$1']}]). - - + [list_to_tuple(['orelse' | [{'=:=', '$2', RKey} || + RKey <- RoutingKeys]])]). %%-------------------------------------------------------------------- @@ -117,3 +114,25 @@ lookup_qpids(QNames) -> [] -> QPids end end, [], QNames). + +%% Normally we'd call mnesia:dirty_select/2 here, but that is quite +%% expensive due to +%% +%% 1) general mnesia overheads (figuring out table types and +%% locations, etc). We get away with bypassing these because we know +%% that the table +%% - is not the schema table +%% - has a local ram copy +%% - does not have any indices +%% +%% 2) 'fixing' of the table with ets:safe_fixtable/2, which is wholly +%% unnecessary. According to the ets docs (and the code in erl_db.c), +%% 'select' is safe anyway ("Functions that internally traverse over a +%% table, like select and match, will give the same guarantee as +%% safe_fixtable.") and, furthermore, even the lower level iterators +%% ('first' and 'next') are safe on ordered_set tables ("Note that for +%% tables of the ordered_set type, safe_fixtable/2 is not necessary as +%% calls to first/1 and next/2 will always succeed."), which +%% rabbit_route is. +find_routes(MatchHead, Conditions) -> + ets:select(rabbit_route, [{MatchHead, Conditions, ['$1']}]). |