diff --git a/apps/antidote_crdt/src/antidote_crdt_map_go.erl b/apps/antidote_crdt/src/antidote_crdt_map_go.erl index bec421df..bdc8600a 100644 --- a/apps/antidote_crdt/src/antidote_crdt_map_go.erl +++ b/apps/antidote_crdt/src/antidote_crdt_map_go.erl @@ -176,6 +176,16 @@ update2_test() -> Map1 = new(), {ok, Effect1} = downstream({update, [{{a, antidote_crdt_set_aw}, {add, a}}]}, Map1), {ok, Map2} = update(Effect1, Map1), - ?assertEqual([{{a, antidote_crdt_set_aw}, [a]}], value(Map2)). + ?assertEqual([{{a, antidote_crdt_set_aw}, [a]}], value(Map2)), + Op = {update, [ + {{a, antidote_crdt_set_aw}, {add, a}}, + {{a, antidote_crdt_set_aw}, {add, b}}, + {{a, antidote_crdt_set_aw}, {add, c}}, + {{a, antidote_crdt_set_aw}, {remove, a}} + ]}, + ?assert(is_operation(Op)), + {ok, Effect2} = downstream(Op, Map2), + {ok, Map3} = update(Effect2, Map2), + ?assertEqual([{{a, antidote_crdt_set_aw}, [ b, c]}], value(Map3)). -endif. diff --git a/apps/antidote_crdt/src/antidote_crdt_map_rr.erl b/apps/antidote_crdt/src/antidote_crdt_map_rr.erl index c27622bb..4b959774 100644 --- a/apps/antidote_crdt/src/antidote_crdt_map_rr.erl +++ b/apps/antidote_crdt/src/antidote_crdt_map_rr.erl @@ -141,6 +141,7 @@ generate_downstream_update({{Key, Type}, Op}, CurrentMap) -> false -> antidote_crdt:new(Type) end, {ok, DownstreamEffect} = antidote_crdt:downstream(Type, Op, CurrentState), + io:format("effect: ~p~n", [DownstreamEffect]), {{Key, Type}, {ok, DownstreamEffect}}. -spec generate_downstream_remove(typedKey(), state()) -> nested_downstream(). @@ -384,6 +385,19 @@ upd(Update, State) -> {ok, Res} = update(Downstream, State), Res. +multiple_ops_on_same_key_test() -> + M1 = new(), + Op = {update, [ + {{a, antidote_crdt_set_rw}, {remove, <<"c">>}}, + {{a, antidote_crdt_set_rw}, {add, <<"c">>}} + ]}, + ?assert(is_operation(Op)), + M2 = upd(Op, M1), + Op2 = {update, {{a, antidote_crdt_set_rw}, {remove, <<"c">>}}}, + Op3 = {update, {{a, antidote_crdt_set_rw}, {add, <<"c">>}}}, + M3 = upd(Op3, upd(Op2, M1)), + ?assertEqual(value(M3), value(M2)). + remove_test() -> M1 = new(), ?assertEqual([], value(M1)), diff --git a/apps/antidote_crdt/test/prop_map_go.erl b/apps/antidote_crdt/test/prop_map_go.erl index ba43da47..07fdc213 100644 --- a/apps/antidote_crdt/test/prop_map_go.erl +++ b/apps/antidote_crdt/test/prop_map_go.erl @@ -64,16 +64,9 @@ op() -> ?SIZED(Size, op(Size)). op(Size) -> {update, oneof([ nestedOp(Size), - ?LET(L, list(nestedOp(Size div 2)), removeDuplicateKeys(L, [])) + ?LET(L, list(nestedOp(Size div 2)), L) ])}. -removeDuplicateKeys([], _) -> []; -removeDuplicateKeys([{Key, Op}|Rest], Keys) -> - case lists:member(Key, Keys) of - true -> removeDuplicateKeys(Rest, Keys); - false -> [{Key, Op}|removeDuplicateKeys(Rest, [Key|Keys])] - end. - nestedOp(Size) -> oneof( [ diff --git a/apps/antidote_crdt/test/prop_map_rr.erl b/apps/antidote_crdt/test/prop_map_rr.erl index fabc03d6..2f1b82ac 100644 --- a/apps/antidote_crdt/test/prop_map_rr.erl +++ b/apps/antidote_crdt/test/prop_map_rr.erl @@ -99,26 +99,17 @@ op() -> ?SIZED(Size, op(Size)). op(Size) -> oneof([ {update, nestedOp(Size)}, - {update, ?LET(L, list(nestedOp(Size div 2)), removeDuplicateKeys(L, []))}, + {update, ?LET(L, list(nestedOp(Size div 2)), L)}, {remove, typed_key()}, - {remove, ?LET(L, list(typed_key()), lists:usort(L))}, + {remove, ?LET(L, list(typed_key()), L)}, ?LET({Updates, Removes}, {list(nestedOp(Size div 2)), list(typed_key())}, begin - Removes2 = lists:usort(Removes), - Updates2 = removeDuplicateKeys(Updates, Removes2), - {batch, {Updates2, Removes2}} + {batch, {Updates, Removes}} end), {reset, {}} ]). -removeDuplicateKeys([], _) -> []; -removeDuplicateKeys([{Key, Op}|Rest], Keys) -> - case lists:member(Key, Keys) of - true -> removeDuplicateKeys(Rest, Keys); - false -> [{Key, Op}|removeDuplicateKeys(Rest, [Key|Keys])] - end. - nestedOp(Size) -> oneof( [ @@ -141,8 +132,3 @@ crdt_type() -> key() -> oneof([key1, key2, key3, key4]). - - - - -