diff options
author | Matthias Radestock <matthias@rabbitmq.com> | 2012-09-15 13:25:10 +0100 |
---|---|---|
committer | Matthias Radestock <matthias@rabbitmq.com> | 2012-09-15 13:25:10 +0100 |
commit | 82428758641f8ec6d955cb34aade975cdd659d2e (patch) | |
tree | 4e2d93093853c9917d4897494e000159d9fd9bec /src/rabbit_binding.erl | |
parent | 7cf07f3020439490d4ef62536a27a58f8fa1fc7f (diff) | |
download | rabbitmq-server-82428758641f8ec6d955cb34aade975cdd659d2e.tar.gz |
bring queue/exchange removal cost back down to O(binding_count)
by performing all mnesia read operations before writes
Diffstat (limited to 'src/rabbit_binding.erl')
-rw-r--r-- | src/rabbit_binding.erl | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/src/rabbit_binding.erl b/src/rabbit_binding.erl index 540e221f..a7730a1a 100644 --- a/src/rabbit_binding.erl +++ b/src/rabbit_binding.erl @@ -277,21 +277,21 @@ has_for_source(SrcName) -> remove_for_source(SrcName) -> lock_route_tables(), Match = #route{binding = #binding{source = SrcName, _ = '_'}}, - Routes = lists:usort( - mnesia:match_object(rabbit_route, Match, write) ++ - mnesia:match_object(rabbit_durable_route, Match, write)), - [begin - sync_route(Route, fun delete_object/3), - Route#route.binding - end || Route <- Routes]. - -remove_for_destination(Dst) -> - remove_for_destination( - Dst, fun (R) -> sync_route(R, fun delete_object/3) end). + remove_routes( + lists:usort(mnesia:match_object(rabbit_route, Match, write) ++ + mnesia:match_object(rabbit_durable_route, Match, write))). + +remove_for_destination(DstName) -> + remove_for_destination(DstName, fun remove_routes/1). -remove_transient_for_destination(Dst) -> +remove_transient_for_destination(DstName) -> remove_for_destination( - Dst, fun (R) -> sync_transient_route(R, fun delete_object/3) end). + DstName, fun (Routes) -> + [begin + ok = sync_transient_route(R, fun delete_object/3), + R#route.binding + end || R <- Routes] + end). %%---------------------------------------------------------------------------- @@ -378,16 +378,26 @@ lock_route_tables() -> rabbit_semi_durable_route, rabbit_durable_route]]. -remove_for_destination(DstName, DeleteFun) -> +remove_routes(Routes) -> + %% This partitioning allows us to suppress unnecessary delete + %% operations on disk tables, which require an fsync. + {TransientRoutes, DurableRoutes} = + lists:partition(fun (R) -> mnesia:match_object( + rabbit_durable_route, R, write) == [] end, + Routes), + [ok = sync_transient_route(R, fun mnesia:delete_object/3) || + R <- TransientRoutes], + [ok = sync_route(R, fun mnesia:delete_object/3) || + R <- DurableRoutes], + [R#route.binding || R <- Routes]. + +remove_for_destination(DstName, Fun) -> lock_route_tables(), Match = reverse_route( #route{binding = #binding{destination = DstName, _ = '_'}}), - ReverseRoutes = mnesia:match_object(rabbit_reverse_route, Match, write), - Bindings = [begin - Route = reverse_route(ReverseRoute), - ok = DeleteFun(Route), - Route#route.binding - end || ReverseRoute <- ReverseRoutes], + Routes = [reverse_route(R) || R <- mnesia:match_object( + rabbit_reverse_route, Match, write)], + Bindings = Fun(Routes), group_bindings_fold(fun maybe_auto_delete/3, new_deletions(), lists:keysort(#binding.source, Bindings)). |