diff options
author | Dániel Szoboszlay <[email protected]> | 2019-01-04 15:26:26 +0100 |
---|---|---|
committer | Dániel Szoboszlay <[email protected]> | 2019-01-22 12:27:38 +0100 |
commit | 69bff908293f00e242a8f0776efff0c3765ce235 (patch) | |
tree | 0239ca2339464629608d5b678f0f9b20b6fb29bf /lib/mnesia/src | |
parent | bd1131fba3525599156ee685cdb8621b8e8d84a9 (diff) | |
download | otp-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/src')
-rw-r--r-- | lib/mnesia/src/mnesia_dumper.erl | 31 |
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), |