aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mnesia
diff options
context:
space:
mode:
authorDániel Szoboszlay <[email protected]>2019-01-04 15:26:26 +0100
committerDániel Szoboszlay <[email protected]>2019-01-22 12:27:38 +0100
commit69bff908293f00e242a8f0776efff0c3765ce235 (patch)
tree0239ca2339464629608d5b678f0f9b20b6fb29bf /lib/mnesia
parentbd1131fba3525599156ee685cdb8621b8e8d84a9 (diff)
downloadotp-69bff908293f00e242a8f0776efff0c3765ce235.tar.gz
otp-69bff908293f00e242a8f0776efff0c3765ce235.tar.bz2
otp-69bff908293f00e242a8f0776efff0c3765ce235.zip
Optimise ext table dumping
The original algorithm first grouped ops in a commit by ext engine type via folding over the list with orddict:append/3, that resulted in an O(n^2) algorithm. However, grouping the ops is not needed, the ops can be dispatched to insert_op/6 one-by-one, after looking up the storage semantics of their respective engine. This is a much cheaper algorithm, assuming looking up the storage semantics is cheap (which should be).
Diffstat (limited to 'lib/mnesia')
-rw-r--r--lib/mnesia/src/mnesia_dumper.erl31
1 files changed, 19 insertions, 12 deletions
diff --git a/lib/mnesia/src/mnesia_dumper.erl b/lib/mnesia/src/mnesia_dumper.erl
index a2880d6cf4..964f1f5b7d 100644
--- a/lib/mnesia/src/mnesia_dumper.erl
+++ b/lib/mnesia/src/mnesia_dumper.erl
@@ -272,17 +272,12 @@ do_insert_rec(Tid, Rec, InPlace, InitBy, LogV) ->
end
end,
D = Rec#commit.disc_copies,
- ExtOps = commit_ext(Rec),
insert_ops(Tid, disc_copies, D, InPlace, InitBy, LogV),
- [insert_ops(Tid, Ext, Ops, InPlace, InitBy, LogV) ||
- {Ext, Ops} <- ExtOps,
- storage_semantics(Ext) == disc_copies],
+ insert_ext_ops(Tid, commit_ext(Rec), InPlace, InitBy),
case InitBy of
startup ->
DO = Rec#commit.disc_only_copies,
- insert_ops(Tid, disc_only_copies, DO, InPlace, InitBy, LogV),
- [insert_ops(Tid, Ext, Ops, InPlace, InitBy, LogV) ||
- {Ext, Ops} <- ExtOps, storage_semantics(Ext) == disc_only_copies];
+ insert_ops(Tid, disc_only_copies, DO, InPlace, InitBy, LogV);
_ ->
ignore
end.
@@ -290,11 +285,8 @@ do_insert_rec(Tid, Rec, InPlace, InitBy, LogV) ->
commit_ext(#commit{ext = []}) -> [];
commit_ext(#commit{ext = Ext}) ->
case lists:keyfind(ext_copies, 1, Ext) of
- {_, C} ->
- lists:foldl(fun({Ext0, Op}, D) ->
- orddict:append(Ext0, Op, D)
- end, orddict:new(), C);
- false -> []
+ {_, C} -> C;
+ false -> []
end.
update(_Tid, [], _DumperMode) ->
@@ -330,6 +322,21 @@ perform_update(Tid, SchemaOps, _DumperMode, _UseDir) ->
fatal("Schema update error ~tp ~tp", [{Reason,ST}, SchemaOps])
end.
+insert_ext_ops(Tid, ExtOps, InPlace, InitBy) ->
+ %% Note: ext ops cannot be part of pre-4.3 logs, so there's no need
+ %% to support the old operation order, as in `insert_ops'
+ lists:foreach(
+ fun ({Ext, Op}) ->
+ case storage_semantics(Ext) of
+ Semantics when Semantics == disc_copies;
+ Semantics == disc_only_copies, InitBy == startup ->
+ insert_op(Tid, Ext, Op, InPlace, InitBy);
+ _Other ->
+ ok
+ end
+ end,
+ ExtOps).
+
insert_ops(_Tid, _Storage, [], _InPlace, _InitBy, _) -> ok;
insert_ops(Tid, Storage, [Op], InPlace, InitBy, Ver) when Ver >= "4.3"->
insert_op(Tid, Storage, Op, InPlace, InitBy),