From 482cde369a02391b30511e10fb24a1a836d643e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Fr=C3=B6berg?= Date: Mon, 19 Nov 2018 15:28:37 +0100 Subject: 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(-) (limited to 'lib') 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. -- cgit v1.2.3 From 8332bff4ceebd08d103623f59f7761d8e9367f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Fr=C3=B6berg?= Date: Wed, 28 Nov 2018 11:59:19 +0100 Subject: Fall back to default locking if LockKind is not read or write --- lib/mnesia/src/mnesia.erl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl index 89b7207483..77afb8250c 100644 --- a/lib/mnesia/src/mnesia.erl +++ b/lib/mnesia/src/mnesia.erl @@ -851,7 +851,7 @@ read(Tid, Ts, Tab, Key, LockKind) abort({bad_type, Tab, LockKind}) end end, - add_written(?ets_lookup(Store, Oid), Tab, ObjsFun); + add_written(?ets_lookup(Store, Oid), Tab, ObjsFun, LockKind); _Protocol -> dirty_read(Tab, Key) end; @@ -1207,13 +1207,17 @@ add_previous(_Tid, Ts, _Type, Tab) -> %% 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, ObjsFun) -> +add_written([], _Tab, ObjsFun, _LockKind) -> ObjsFun(); % standard normal fast case -add_written(Written, Tab, ObjsFun) -> +add_written(Written, Tab, ObjsFun, LockKind) -> case val({Tab, setorbag}) of bag -> add_written_to_bag(Written, ObjsFun(), []); + _ when LockKind == read; + LockKind == write -> + add_written_to_set(Written); _ -> + _ = ObjsFun(), % Fall back to request new lock and read from source add_written_to_set(Written) end. -- cgit v1.2.3