diff options
Diffstat (limited to 'lib/mnesia')
-rw-r--r-- | lib/mnesia/src/mnesia_index.erl | 27 | ||||
-rw-r--r-- | lib/mnesia/test/mnesia_dirty_access_test.erl | 19 |
2 files changed, 35 insertions, 11 deletions
diff --git a/lib/mnesia/src/mnesia_index.erl b/lib/mnesia/src/mnesia_index.erl index 81ed5a8f1a..0c882c0df6 100644 --- a/lib/mnesia/src/mnesia_index.erl +++ b/lib/mnesia/src/mnesia_index.erl @@ -70,17 +70,24 @@ add_index(Index, Tab, Key, Obj, Old) -> add_index2([{Pos, Ixt} |Tail], bag, Tab, K, Obj, OldRecs) -> db_put(Ixt, {element(Pos, Obj), K}), add_index2(Tail, bag, Tab, K, Obj, OldRecs); -add_index2([{Pos, Ixt} |Tail], Type, Tab, K, Obj, OldRecs) -> +add_index2([{Pos, Ixt} |Tail], Type, Tab, K, Obj, OldRecs0) -> %% Remove old tuples in index if Tab is updated - case OldRecs of - undefined -> - Old = mnesia_lib:db_get(Tab, K), - del_ixes(Ixt, Old, Pos, K); - Old -> - del_ixes(Ixt, Old, Pos, K) - end, - db_put(Ixt, {element(Pos, Obj), K}), - add_index2(Tail, Type, Tab, K, Obj, OldRecs); + OldRecs1 = case OldRecs0 of + undefined -> mnesia_lib:db_get(Tab, K); + _ -> OldRecs0 + end, + IdxVal = element(Pos, Obj), + case [Old || Old <- OldRecs1, element(Pos, Old) =/= IdxVal] of + [] when OldRecs1 =:= [] -> %% Write + db_put(Ixt, {element(Pos, Obj), K}), + add_index2(Tail, Type, Tab, K, Obj, OldRecs0); + [] -> %% when OldRecs1 =/= [] Update without modifying index field + add_index2(Tail, Type, Tab, K, Obj, OldRecs0); + OldRecs -> %% Update + db_put(Ixt, {element(Pos, Obj), K}), + del_ixes(Ixt, OldRecs, Pos, K), + add_index2(Tail, Type, Tab, K, Obj, OldRecs0) + end; add_index2([], _, _Tab, _K, _Obj, _) -> ok. delete_index(Index, Tab, K) -> diff --git a/lib/mnesia/test/mnesia_dirty_access_test.erl b/lib/mnesia/test/mnesia_dirty_access_test.erl index 89aff2b3b8..0d57e5a1b1 100644 --- a/lib/mnesia/test/mnesia_dirty_access_test.erl +++ b/lib/mnesia/test/mnesia_dirty_access_test.erl @@ -401,9 +401,26 @@ dirty_index_read(Config, Storage) -> ?match({'EXIT', _}, mnesia:dirty_index_read(Tab, 2, BadValPos)), ?match({'EXIT', _}, mnesia:dirty_index_read(foo, 2, ValPos)), ?match({'EXIT', _}, mnesia:dirty_index_read([], 2, ValPos)), - + + mnesia:dirty_write({Tab, 5, 1}), + ?match(ok, index_read_loop(Tab, 0)), + ?verify_mnesia(Nodes, []). + +index_read_loop(Tab, N) when N =< 1000 -> + spawn_link(fun() -> + mnesia:transaction(fun() -> mnesia:write({Tab, 5, 1}) end) + end), + case mnesia:dirty_match_object({Tab, '_', 1}) of + [{Tab, 5, 1}] -> + index_read_loop(Tab, N+1); + Other -> {N, Other} + end; +index_read_loop(_, _) -> + ok. + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |