Skip to content

Commit da4a6c0

Browse files
Merge pull request rabbitmq#1715 from rabbitmq/bindings-optimisation
Bindings optimisation
2 parents c1fb658 + a9dc1f8 commit da4a6c0

File tree

2 files changed

+37
-19
lines changed

2 files changed

+37
-19
lines changed

src/rabbit_binding.erl

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ recover_semi_durable_route(Gatherer, R = #route{binding = B}, ToRecover) ->
145145
recover_semi_durable_route_txn(R = #route{binding = B}, X) ->
146146
rabbit_misc:execute_mnesia_transaction(
147147
fun () ->
148-
case mnesia:match_object(rabbit_semi_durable_route, R, read) of
148+
case mnesia:read(rabbit_semi_durable_route, B, read) of
149149
[] -> no_recover;
150150
_ -> ok = sync_transient_route(R, fun mnesia:write/3),
151151
rabbit_exchange:serial(X)
@@ -232,7 +232,7 @@ remove(Src, Dst, B, ActingUser) ->
232232
lock_resource(Src),
233233
lock_resource(Dst),
234234
ok = sync_route(#route{binding = B}, durable(Src), durable(Dst),
235-
fun mnesia:delete_object/3),
235+
fun delete/3),
236236
Deletions = maybe_auto_delete(
237237
B#binding.source, [B], new_deletions(), false),
238238
process_deletions(Deletions, ActingUser).
@@ -319,8 +319,8 @@ remove_for_source(SrcName) ->
319319
Match = #route{binding = #binding{source = SrcName, _ = '_'}},
320320
remove_routes(
321321
lists:usort(
322-
mnesia:match_object(rabbit_route, Match, read) ++
323-
mnesia:match_object(rabbit_semi_durable_route, Match, read))).
322+
mnesia:dirty_match_object(rabbit_route, Match) ++
323+
mnesia:dirty_match_object(rabbit_semi_durable_route, Match))).
324324

325325
remove_for_destination(DstName, OnlyDurable) ->
326326
remove_for_destination(DstName, OnlyDurable, fun remove_routes/1).
@@ -406,21 +406,33 @@ remove_routes(Routes) ->
406406
%% This partitioning allows us to suppress unnecessary delete
407407
%% operations on disk tables, which require an fsync.
408408
{RamRoutes, DiskRoutes} =
409-
lists:partition(fun (R) -> mnesia:match_object(
410-
rabbit_durable_route, R, read) == [] end,
409+
lists:partition(fun (R) -> mnesia:read(
410+
rabbit_durable_route, R#route.binding, read) == [] end,
411411
Routes),
412+
{RamOnlyRoutes, SemiDurableRoutes} =
413+
lists:partition(fun (R) -> mnesia:read(
414+
rabbit_semi_durable_route, R#route.binding, read) == [] end,
415+
RamRoutes),
412416
%% Of course the destination might not really be durable but it's
413417
%% just as easy to try to delete it from the semi-durable table
414418
%% than check first
415-
[ok = sync_route(R, false, true, fun mnesia:delete_object/3) ||
416-
R <- RamRoutes],
417-
[ok = sync_route(R, true, true, fun mnesia:delete_object/3) ||
419+
[ok = sync_route(R, true, true, fun delete/3) ||
418420
R <- DiskRoutes],
421+
[ok = sync_route(R, false, true, fun delete/3) ||
422+
R <- SemiDurableRoutes],
423+
[ok = sync_route(R, false, false, fun delete/3) ||
424+
R <- RamOnlyRoutes],
419425
[R#route.binding || R <- Routes].
420426

427+
428+
delete(Tab, #route{binding = B}, LockKind) ->
429+
mnesia:delete(Tab, B, LockKind);
430+
delete(Tab, #reverse_route{reverse_binding = B}, LockKind) ->
431+
mnesia:delete(Tab, B, LockKind).
432+
421433
remove_transient_routes(Routes) ->
422434
[begin
423-
ok = sync_transient_route(R, fun mnesia:delete_object/3),
435+
ok = sync_transient_route(R, fun delete/3),
424436
R#route.binding
425437
end || R <- Routes].
426438

@@ -431,13 +443,13 @@ remove_for_destination(DstName, OnlyDurable, Fun) ->
431443
Routes = case OnlyDurable of
432444
false ->
433445
[reverse_route(R) ||
434-
R <- mnesia:match_object(
435-
rabbit_reverse_route, MatchRev, read)];
446+
R <- mnesia:dirty_match_object(
447+
rabbit_reverse_route, MatchRev)];
436448
true -> lists:usort(
437-
mnesia:match_object(
438-
rabbit_durable_route, MatchFwd, read) ++
439-
mnesia:match_object(
440-
rabbit_semi_durable_route, MatchFwd, read))
449+
mnesia:dirty_match_object(
450+
rabbit_durable_route, MatchFwd) ++
451+
mnesia:dirty_match_object(
452+
rabbit_semi_durable_route, MatchFwd))
441453
end,
442454
Bindings = Fun(Routes),
443455
group_bindings_fold(fun maybe_auto_delete/4, new_deletions(),

src/rabbit_exchange.erl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,15 +492,21 @@ maybe_auto_delete(#exchange{auto_delete = true} = X, OnlyDurable) ->
492492

493493
conditional_delete(X = #exchange{name = XName}, OnlyDurable) ->
494494
case rabbit_binding:has_for_source(XName) of
495-
false -> unconditional_delete(X, OnlyDurable);
495+
false -> internal_delete(X, OnlyDurable, false);
496496
true -> {error, in_use}
497497
end.
498498

499-
unconditional_delete(X = #exchange{name = XName}, OnlyDurable) ->
499+
unconditional_delete(X, OnlyDurable) ->
500+
internal_delete(X, OnlyDurable, true).
501+
502+
internal_delete(X = #exchange{name = XName}, OnlyDurable, RemoveBindingsForSource) ->
500503
ok = mnesia:delete({rabbit_exchange, XName}),
501504
ok = mnesia:delete({rabbit_exchange_serial, XName}),
502505
mnesia:delete({rabbit_durable_exchange, XName}),
503-
Bindings = rabbit_binding:remove_for_source(XName),
506+
Bindings = case RemoveBindingsForSource of
507+
true -> rabbit_binding:remove_for_source(XName);
508+
false -> []
509+
end,
504510
{deleted, X, Bindings, rabbit_binding:remove_for_destination(
505511
XName, OnlyDurable)}.
506512

0 commit comments

Comments
 (0)