From 69bff908293f00e242a8f0776efff0c3765ce235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Szoboszlay?= Date: Fri, 4 Jan 2019 15:26:26 +0100 Subject: 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). --- lib/mnesia/src/mnesia_dumper.erl | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'lib') 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), -- cgit v1.2.3