File 1431-Optimise-ext-table-dumping.patch of Package erlang

From 69bff908293f00e242a8f0776efff0c3765ce235 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=A1niel=20Szoboszlay?= <daniel.szoboszlay@klarna.com>
Date: Fri, 4 Jan 2019 15:26:26 +0100
Subject: [PATCH] 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(-)

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),
-- 
2.16.4