File 0539-Mnesia-should-always-use-the-local-context-if-availa.patch of Package erlang

From 482cde369a02391b30511e10fb24a1a836d643e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Magnus=20Fr=C3=B6berg?= <magnus@klarna.com>
Date: Mon, 19 Nov 2018 15:28:37 +0100
Subject: [PATCH 1/2] Mnesia should always use the local context if available

Do not read from (set | order_set) source table if the content is
already in the transactional context (i.e., a previous write/delete).
---
 lib/mnesia/src/mnesia.erl | 36 ++++++++++++++++++++----------------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl
index 223dba3f90..89b7207483 100644
--- a/lib/mnesia/src/mnesia.erl
+++ b/lib/mnesia/src/mnesia.erl
@@ -838,18 +838,20 @@ read(Tid, Ts, Tab, Key, LockKind)
 	tid ->
 	    Store = Ts#tidstore.store,
 	    Oid = {Tab, Key},
-	    Objs =
-		case LockKind of
-		    read ->
-			mnesia_locker:rlock(Tid, Store, Oid);
-		    write ->
-			mnesia_locker:rwlock(Tid, Store, Oid);
-		    sticky_write ->
-			mnesia_locker:sticky_rwlock(Tid, Store, Oid);
-		    _ ->
-			abort({bad_type, Tab, LockKind})
-		end,
-	    add_written(?ets_lookup(Store, Oid), Tab, Objs);
+	    ObjsFun =
+                fun() ->
+                        case LockKind of
+                            read ->
+                                mnesia_locker:rlock(Tid, Store, Oid);
+                            write ->
+                                mnesia_locker:rwlock(Tid, Store, Oid);
+                            sticky_write ->
+                                mnesia_locker:sticky_rwlock(Tid, Store, Oid);
+                            _ ->
+                                abort({bad_type, Tab, LockKind})
+                        end
+                end,
+	    add_written(?ets_lookup(Store, Oid), Tab, ObjsFun);
 	_Protocol ->
 	    dirty_read(Tab, Key)
     end;
@@ -1202,13 +1204,15 @@ add_previous(_Tid, Ts, _Type, Tab) ->
 %% This routine fixes up the return value from read/1 so that
 %% it is correct with respect to what this particular transaction
 %% has already written, deleted .... etc
+%% The actual read from the table is not done if not needed due to local
+%% transaction context, and if so, no extra read lock is needed either.
 
-add_written([], _Tab, Objs) ->
-    Objs;  % standard normal fast case
-add_written(Written, Tab, Objs) ->
+add_written([], _Tab, ObjsFun) ->
+    ObjsFun();  % standard normal fast case
+add_written(Written, Tab, ObjsFun) ->
     case val({Tab, setorbag}) of
 	bag ->
-	    add_written_to_bag(Written, Objs, []);
+	    add_written_to_bag(Written, ObjsFun(), []);
 	_   ->
 	    add_written_to_set(Written)
     end.
-- 
2.16.4

openSUSE Build Service is sponsored by