From 017bb883589c7797764dab7abc35e6a859f96d55 Mon Sep 17 00:00:00 2001 From: Georges Younes Date: Mon, 22 Jan 2018 15:37:50 +0000 Subject: [PATCH 1/6] rename; refactor --- TEST-file_antidote_crdt.app.xml | 489 ++++++++++++++++++ include/antidote_crdt.hrl | 13 +- src/antidote_crdt.erl | 51 +- src/antidote_crdt_map.erl | 95 ---- ...tidote_crdt_bcounter.erl => counter_b.erl} | 60 +-- ...e_crdt_fat_counter.erl => counter_fat.erl} | 5 +- ...tidote_crdt_counter.erl => counter_pn.erl} | 28 +- ...{antidote_crdt_flag_dw.erl => flag_dw.erl} | 18 +- ...{antidote_crdt_flag_ew.erl => flag_ew.erl} | 16 +- ...antidote_crdt_flag.erl => flag_helper.erl} | 4 +- ...{antidote_crdt_integer.erl => integer.erl} | 4 +- src/{antidote_crdt_map_aw.erl => map_aw.erl} | 23 +- src/{antidote_crdt_gmap.erl => map_go.erl} | 30 +- src/{antidote_crdt_map_rr.erl => map_rr.erl} | 48 +- ...idote_crdt_lwwreg.erl => register_lww.erl} | 12 +- ...ntidote_crdt_mvreg.erl => register_mv.erl} | 32 +- src/{antidote_crdt_rga.erl => rga.erl} | 2 +- src/{antidote_crdt_orset.erl => set_aw.erl} | 116 ++--- src/{antidote_crdt_gset.erl => set_go.erl} | 14 +- src/{antidote_crdt_set_rw.erl => set_rw.erl} | 22 +- ...t_fat_counter.erl => prop_counter_fat.erl} | 12 +- ...p_crdt_counter.erl => prop_counter_pn.erl} | 12 +- ...prop_crdt_flag_dw.erl => prop_flag_dw.erl} | 4 +- ...prop_crdt_flag_ew.erl => prop_flag_ew.erl} | 4 +- ...prop_crdt_integer.erl => prop_integer.erl} | 8 +- .../{prop_crdt_map_aw.erl => prop_map_aw.erl} | 29 +- test/{prop_crdt_gmap.erl => prop_map_go.erl} | 27 +- .../{prop_crdt_map_rr.erl => prop_map_rr.erl} | 30 +- ..._crdt_lwwreg.erl => prop_register_lww.erl} | 8 +- ...op_crdt_mvreg.erl => prop_register_mv.erl} | 10 +- test/{prop_crdt_orset.erl => prop_set_aw.erl} | 17 +- test/{prop_crdt_gset.erl => prop_set_go.erl} | 12 +- .../{prop_crdt_set_rw.erl => prop_set_rw.erl} | 12 +- 33 files changed, 826 insertions(+), 441 deletions(-) create mode 100644 TEST-file_antidote_crdt.app.xml delete mode 100644 src/antidote_crdt_map.erl rename src/{antidote_crdt_bcounter.erl => counter_b.erl} (84%) rename src/{antidote_crdt_fat_counter.erl => counter_fat.erl} (97%) rename src/{antidote_crdt_counter.erl => counter_pn.erl} (90%) rename src/{antidote_crdt_flag_dw.erl => flag_dw.erl} (80%) rename src/{antidote_crdt_flag_ew.erl => flag_ew.erl} (85%) rename src/{antidote_crdt_flag.erl => flag_helper.erl} (94%) rename src/{antidote_crdt_integer.erl => integer.erl} (97%) rename src/{antidote_crdt_map_aw.erl => map_aw.erl} (95%) rename src/{antidote_crdt_gmap.erl => map_go.erl} (83%) rename src/{antidote_crdt_map_rr.erl => map_rr.erl} (87%) rename src/{antidote_crdt_lwwreg.erl => register_lww.erl} (86%) rename src/{antidote_crdt_mvreg.erl => register_mv.erl} (82%) rename src/{antidote_crdt_rga.erl => rga.erl} (99%) rename src/{antidote_crdt_orset.erl => set_aw.erl} (77%) rename src/{antidote_crdt_gset.erl => set_go.erl} (85%) rename src/{antidote_crdt_set_rw.erl => set_rw.erl} (95%) rename test/{prop_crdt_fat_counter.erl => prop_counter_fat.erl} (79%) rename test/{prop_crdt_counter.erl => prop_counter_pn.erl} (82%) rename test/{prop_crdt_flag_dw.erl => prop_flag_dw.erl} (92%) rename test/{prop_crdt_flag_ew.erl => prop_flag_ew.erl} (92%) rename test/{prop_crdt_integer.erl => prop_integer.erl} (90%) rename test/{prop_crdt_map_aw.erl => prop_map_aw.erl} (84%) rename test/{prop_crdt_gmap.erl => prop_map_go.erl} (80%) rename test/{prop_crdt_map_rr.erl => prop_map_rr.erl} (79%) rename test/{prop_crdt_lwwreg.erl => prop_register_lww.erl} (91%) rename test/{prop_crdt_mvreg.erl => prop_register_mv.erl} (84%) rename test/{prop_crdt_orset.erl => prop_set_aw.erl} (86%) rename test/{prop_crdt_gset.erl => prop_set_go.erl} (84%) rename test/{prop_crdt_set_rw.erl => prop_set_rw.erl} (88%) diff --git a/TEST-file_antidote_crdt.app.xml b/TEST-file_antidote_crdt.app.xml new file mode 100644 index 0000000..d9bc309 --- /dev/null +++ b/TEST-file_antidote_crdt.app.xml @@ -0,0 +1,489 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FatCnt0 = [] +Increment1 = {<<62,229,225,101,155,99,133,91,227,61,11,235,224,164,183,38,103, + 164,236,116>>, + 5} +FatCnt1 = [{<<62,229,225,101,155,99,133,91,227,61,11,235,224,164,183,38,103, + 164,236,116>>, + 5}] +Decrement1 = {<<109,42,58,116,201,67,165,127,35,89,44,40,33,170,78,250,42,8, + 202,146>>, + -2} +FatCnt2 = [{<<62,229,225,101,155,99,133,91,227,61,11,235,224,164,183,38,103, + 164,236,116>>, + 5}, + {<<109,42,58,116,201,67,165,127,35,89,44,40,33,170,78,250,42,8,202, + 146>>, + -2}] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Reset1Effect = {[<<195,210,219,190,70,145,56,165,234,10,186,120,85,149,20,34, + 217,1,76,53>>], + []} +Enable1Effect = {[], + [<<195,210,219,190,70,145,56,165,234,10,186,120,85,149,20, + 34,217,1,76,53>>]} +Flag1a = [<<195,210,219,190,70,145,56,165,234,10,186,120,85,149,20,34,217,1, + 76,53>>] +Flag1b = [] + + + + + + + + + + + + + + + + + + + + + Map0 = {dict,0,16,16,8,80,48, + {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, + {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} +Incr1 = {[{{a,counter_fat}, + {ok,{<<90,217,140,224,131,4,221,75,106,101,16,227,80,36,80,12,72,7, + 129,117>>, + 1}}}], + []} +Map1a = {dict,1,16,16,8,80,48, + {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, + {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[], + [[{a,counter_fat}, + {<<90,217,140,224,131,4,221,75,106,101,16,227,80,36,80,12,72, + 7,129,117>>, + 1}]]}}} +Reset1 = {[], + [{{a,counter_fat}, + {ok,[<<90,217,140,224,131,4,221,75,106,101,16,227,80,36,80,12, + 72,7,129,117>>]}}]} +Map1b = {dict,0,16,16,8,80,48, + {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, + {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} +Remove1 = {[],[{{a,counter_fat},{ok,[]}}]} +Map2a = {dict,0,16,16,8,80,48, + {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, + {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} +Map1c = {dict,0,16,16,8,80,48, + {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, + {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} +Reset2 = {[],[]} +Map1d = {dict,0,16,16,8,80,48, + {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, + {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} +Incr2 = {[{{a,counter_fat}, + {ok,{<<174,93,117,201,201,242,76,191,204,5,14,247,5,12,185,175,182, + 100,250,90>>, + 2}}}], + []} +Map1e = {dict,1,16,16,8,80,48, + {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, + {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[], + [[{a,counter_fat}, + {<<174,93,117,201,201,242,76,191,204,5,14,247,5,12,185,175, + 182,100,250,90>>, + 2}]]}}} + + + + + Map0 = [] +Add1 = {[{{s,set_rw}, + {ok,[{a,[], + [<<144,186,153,131,6,149,158,26,233,139,32,221,203,9,0,167, + 190,251,115,6>>], + []}]}}], + []} +Map1a = [{{s,set_rw},[a]}] +Reset1 = {[], + [{{s,set_rw}, + {ok,[{a,[<<144,186,153,131,6,149,158,26,233,139,32,221,203,9,0, + 167,190,251,115,6>>], + [],[]}]}}]} +Map1b = [] +Remove1 = {[],[{{s,set_rw},{ok,[]}}]} +Map2a = [] +Map1c = [] +Reset2 = {[],[]} +Map1d = [] +Add2 = {[{{s,set_rw}, + {ok,[{b,[], + [<<78,143,165,77,13,204,180,77,155,72,128,231,234,175,100, + 249,27,226,211,37>>], + []}]}}], + []} +Map1e = [{{s,set_rw},[b]}] + + + + + Map0 = {dict,0,16,16,8,80,48, + {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, + {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} +Add1 = {[{{a,map_rr}, + {ok,{[{{a,set_rw}, + {ok,[{a,[], + [<<144,188,135,255,56,206,22,48,242,17,67,44,94,225, + 106,0,102,160,98,53>>], + []}]}}], + []}}}], + []} +Map1a = {dict,1,16,16,8,80,48, + {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, + {{[],[],[],[],[],[],[],[],[], + [[{a,map_rr}| + {dict,1,16,16,8,80,48, + {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, + {{[[{a,set_rw}, + {a, + {[<<144,188,135,255,56,206,22,48,242,17,67,44,94,225,106,0, + 102,160,98,53>>], + []}}]], + [],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}}]], + [],[],[],[],[],[]}}} +Reset1 = {[], + [{{a,map_rr}, + {ok,{[], + [{{a,set_rw}, + {ok,[{a,[<<144,188,135,255,56,206,22,48,242,17,67,44,94, + 225,106,0,102,160,98,53>>], + [],[]}]}}]}}}]} +Map1b = {dict,0,16,16,8,80,48, + {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, + {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} + + + + + Map0 = {dict,0,16,16,8,80,48, + {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, + {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} +Add1 = {[{{b,map_rr},{ok,{[],[{{a,set_rw},{ok,[]}}]}}}],[]} +Map1a = {dict,0,16,16,8,80,48, + {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, + {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} +Remove2 = {[],[{{b,map_rr},{ok,{[],[]}}}]} +Map1b = {dict,0,16,16,8,80,48, + {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, + {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} + + + + + M3 state = [] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ResetEffect = [] +Add1Effect = [{a,[], + [<<9,61,116,97,215,219,20,86,213,51,25,178,50,111,152,180, + 194,50,186,185>>], + []}] +Add2Effect = [{a,[], + [<<71,28,40,1,175,57,53,5,247,160,193,248,52,124,178,189,60, + 234,133,117>>], + []}] +Set1a = [] +Set1b = [{a,{[<<9,61,116,97,215,219,20,86,213,51,25,178,50,111,152,180,194,50, + 186,185>>], + []}}] +Set2a = [{a,{[<<71,28,40,1,175,57,53,5,247,160,193,248,52,124,178,189,60,234, + 133,117>>], + []}}] +Set2b = [{a,{[<<71,28,40,1,175,57,53,5,247,160,193,248,52,124,178,189,60,234, + 133,117>>], + []}}] +Set2c = [{a,{[<<71,28,40,1,175,57,53,5,247,160,193,248,52,124,178,189,60,234, + 133,117>>, + <<9,61,116,97,215,219,20,86,213,51,25,178,50,111,152,180,194,50, + 186,185>>], + []}}] + + + + + + + + + Set0 = [] +Set1 = [{a,{[<<37,12,247,140,101,213,116,236,245,70,75,244,120,124,111,177,94, + 115,136,49>>], + []}}] +Set2 = [{a,{[<<37,12,247,140,101,213,116,236,245,70,75,244,120,124,111,177,94, + 115,136,49>>], + []}}, + {b,{[<<131,76,3,181,249,16,141,78,102,33,17,146,57,89,204,124,242,251, + 152,110>>], + []}}] +Add1Effect = [{a,[], + [<<37,12,247,140,101,213,116,236,245,70,75,244,120,124,111, + 177,94,115,136,49>>], + []}] +Add2Effect = [{b,[], + [<<131,76,3,181,249,16,141,78,102,33,17,146,57,89,204,124, + 242,251,152,110>>], + []}] + + + + + ResetEffect = [] +Add3Effect = [{b,[], + [<<126,192,154,139,181,139,79,137,228,17,57,195,98,27,220, + 129,183,194,162,71>>], + []}] +Set1a = [] +Set3a = [{b,{[<<126,192,154,139,181,139,79,137,228,17,57,195,98,27,220,129, + 183,194,162,71>>], + []}}] +Set1b = [{b,{[<<126,192,154,139,181,139,79,137,228,17,57,195,98,27,220,129, + 183,194,162,71>>], + []}}] + + + + + Remove1Effect = [{b,[],[], + [<<237,78,51,60,180,91,33,189,155,79,254,87,26,186,31, + 197,173,44,142,128>>]}] +Add3Effect = [{a,[], + [<<171,11,140,120,32,164,139,106,199,202,155,28,89,150,30, + 165,212,251,197,140>>], + []}] +Set1a = [{b,{[], + [<<237,78,51,60,180,91,33,189,155,79,254,87,26,186,31,197,173, + 44,142,128>>]}}] +Set3a = [{a,{[<<171,11,140,120,32,164,139,106,199,202,155,28,89,150,30,165, + 212,251,197,140>>], + []}}] +Set1b = [{a,{[<<171,11,140,120,32,164,139,106,199,202,155,28,89,150,30,165, + 212,251,197,140>>], + []}}, + {b,{[], + [<<237,78,51,60,180,91,33,189,155,79,254,87,26,186,31,197,173, + 44,142,128>>]}}] + + + + + Reset3Effect = [] +Add2Effect = [{a,[], + [<<2,163,95,200,95,230,178,240,63,46,227,141,200,45,69,127, + 69,42,149,163>>], + []}] +Set2a = [{a,{[<<2,163,95,200,95,230,178,240,63,46,227,141,200,45,69,127,69,42, + 149,163>>], + []}}] +Set3a = [] +Set3b = [{a,{[<<2,163,95,200,95,230,178,240,63,46,227,141,200,45,69,127,69,42, + 149,163>>], + []}}] + + + + + Reset3Effect = [] +Add2Effect = [{a,[], + [<<95,199,58,253,22,138,220,2,162,254,99,234,151,250,191,58, + 44,131,56,116>>], + []}] +Set2a = [{a,{[<<95,199,58,253,22,138,220,2,162,254,99,234,151,250,191,58,44, + 131,56,116>>], + []}}] +Set3a = [] +Set3b = [{a,{[<<95,199,58,253,22,138,220,2,162,254,99,234,151,250,191,58,44, + 131,56,116>>], + []}}] + + + + + Reset2Effect = [{a,[<<111,20,9,38,112,164,37,29,179,54,244,118,35,168,32,8,78, + 10,26,12>>], + [],[]}] +Add2Effect = [{a,[], + [<<111,20,9,38,112,164,37,29,179,54,244,118,35,168,32,8,78, + 10,26,12>>], + []}] +Set2a = [{a,{[<<111,20,9,38,112,164,37,29,179,54,244,118,35,168,32,8,78,10,26, + 12>>], + []}}] +Set2b = [] + + + + diff --git a/include/antidote_crdt.hrl b/include/antidote_crdt.hrl index 07f300b..1a484ec 100644 --- a/include/antidote_crdt.hrl +++ b/include/antidote_crdt.hrl @@ -4,19 +4,8 @@ -type value() :: term(). -type reason() :: term(). --type pncounter() :: integer(). --type pncounter_update() :: {increment, integer()} | - {decrement, integer()}. --type pncounter_effect() :: integer(). --type pncounter_value() :: integer(). - - -export_type([ crdt/0, update/0, effect/0, - value/0, - pncounter/0, - pncounter_update/0, - pncounter_effect/0, - pncounter_value/0 + value/0 ]). diff --git a/src/antidote_crdt.erl b/src/antidote_crdt.erl index 848487c..8523640 100644 --- a/src/antidote_crdt.erl +++ b/src/antidote_crdt.erl @@ -19,29 +19,46 @@ %% ------------------------------------------------------------------- %% antidote_crdt.erl : behaviour for op-based CRDTs +%% Naming pattern of antidote crdts: _ +%% if there is only one kind of semantics implemented for a certain type +%% only the type is used in the name e.g. rga +%% counter_pn: PN-Counter aka Posistive Negative Counter +%% counter_b: Bounded Counter +%% counter_fat: Fat Counter +%% integer: Integer (Experimental) +%% flag_ew: Enable Wins Flag aka EW-Flag +%% flag_dw: Disable Wins Flag DW-Flag +%% set_go: Grow Only Set aka G-Set +%% set_aw: Add Wins Set aka AW-Set, previously OR-Set (Observed Remove Set) +%% set_rw: Remove Wins Set aka RW-Set +%% register_lww: Last Writer Wins Register aka LWW-Reg +%% register_mv: MultiValue Register aka MV-Reg +%% map_go: Grow Only Map aka G-Map +%% map_aw: Add Wins Map aka AW-Map (Experimental) +%% map_rr: Recursive Resets Map akak RR-Map +%% rga: Replicated Growable Array (Experimental) + -module(antidote_crdt). -include("antidote_crdt.hrl"). --define(CRDTS, [antidote_crdt_counter, - antidote_crdt_orset, - antidote_crdt_gset, - antidote_crdt_rga, - antidote_crdt_bcounter, - antidote_crdt_mvreg, - antidote_crdt_map, - antidote_crdt_lwwreg, - antidote_crdt_gmap, - antidote_crdt_set_rw, - antidote_crdt_integer, - antidote_crdt_map_aw, - antidote_crdt_map_rr, - antidote_crdt_fat_counter, - antidote_crdt_flag_ew, - antidote_crdt_flag_dw - ]). +-define(CRDTS, [counter_pn, + counter_b, + counter_fat, + integer, + flag_ew, + flag_dw, + set_go, + set_aw, + set_rw, + register_lww, + register_mv, + map_go, + map_aw, + map_rr, + rga]). -export([is_type/1 ]). diff --git a/src/antidote_crdt_map.erl b/src/antidote_crdt_map.erl deleted file mode 100644 index 1992f74..0000000 --- a/src/antidote_crdt_map.erl +++ /dev/null @@ -1,95 +0,0 @@ -%% ------------------------------------------------------------------- -%% -%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. -%% -%% This file is provided to you under the Apache License, -%% Version 2.0 (the "License"); you may not use this file -%% except in compliance with the License. You may obtain -%% a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, -%% software distributed under the License is distributed on an -%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -%% KIND, either express or implied. See the License for the -%% specific language governing permissions and limitations -%% under the License. -%% -%% ------------------------------------------------------------------- - -%% @doc module antidote_crdt_gset - A wrapper around riak_dt_gset - --module(antidote_crdt_map). - --behaviour(antidote_crdt). - --ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). --endif. - --define(RIAK_MODULE, riak_dt_map). - --export([ new/0, - value/1, - downstream/2, - update/2, - equal/2, - to_binary/1, - from_binary/1, - is_operation/1, - require_state_downstream/1 - ]). - - --type map_op() :: {update, {[map_field_update() | map_field_op()], actorordot()}}. --type actorordot() :: riak_dt:actor() | riak_dt:dot(). - --type map_field_op() :: {remove, field()}. --type map_field_update() :: {update, field(), crdt_op()}. --type crdt_op() :: term(). %% Valid riak_dt udpates --type field() :: term(). %% riak_dt_map:field(). - -new() -> - ?RIAK_MODULE:new(). - -value(Map) -> - ?RIAK_MODULE:value(Map). - --spec downstream(map_op(), riak_dt:riak_dt_map()) -> {ok, term()}. -downstream({Op, {OpParam, Actor}}, State) -> - {ok, S0} = ?RIAK_MODULE:update({Op, OpParam}, Actor, State), - {ok, {merge, S0}}. - -update({merge, State1}, State2) -> - {ok, ?RIAK_MODULE:merge(State1, State2)}. - -require_state_downstream(_Operation) -> true. - -is_operation({Op, {Param, _Actor}}) -> - ?RIAK_MODULE:is_operation({Op, Param}). - -equal(CRDT1, CRDT2) -> - ?RIAK_MODULE:equal(CRDT1, CRDT2). - -to_binary(CRDT) -> - ?RIAK_MODULE:to_binary(CRDT). - -from_binary(Bin) -> - ?RIAK_MODULE:from_binary(Bin). - --ifdef(TEST). -all_test() -> - S0 = new(), - Field = {'C', riak_dt_pncounter}, - {ok, Downstream} = downstream({update, {[{update, Field, {increment, 1}}], actor}}, S0), - {ok, S1} = update(Downstream, S0), - ?assertEqual([{Field, 1}], value(S1)). - -type_check_test() -> - Res = is_operation({update, {[{update, {key, riak_dt_lwwreg}, {assign, <<"A">>}}, - {update, {val, riak_dt_pncounter}, {increment, 1}}], - hardcodedactor}}), - ?assertEqual(true, Res). - --endif. diff --git a/src/antidote_crdt_bcounter.erl b/src/counter_b.erl similarity index 84% rename from src/antidote_crdt_bcounter.erl rename to src/counter_b.erl index 7be58e0..434eabd 100644 --- a/src/antidote_crdt_bcounter.erl +++ b/src/counter_b.erl @@ -1,7 +1,7 @@ %% -*- coding: utf-8 -*- %% -------------------------------------------------------------------------- %% -%% crdt_bcounter: A convergent, replicated, operation based bounded counter. +%% counter_b: A convergent, replicated, operation-based bounded counter. %% %% -------------------------------------------------------------------------- @@ -12,7 +12,7 @@ %% All operations on this CRDT are monotonic and do not keep extra tombstones. %% @end --module(antidote_crdt_bcounter). +-module(counter_b). -behaviour(antidote_crdt). @@ -40,23 +40,23 @@ -include_lib("eunit/include/eunit.hrl"). -endif. --export_type([bcounter/0, binary_bcounter/0, bcounter_op/0, id/0]). +-export_type([counter_b/0, binary_counter_b/0, counter_b_op/0, id/0]). --opaque bcounter() :: {orddict:orddict(), orddict:orddict()}. --type binary_bcounter() :: binary(). --type bcounter_op() :: bcounter_anon_op() | bcounter_src_op(). --type bcounter_anon_op() :: {transfer, {pos_integer(), id(), id()}} | +-opaque counter_b() :: {orddict:orddict(), orddict:orddict()}. +-type binary_counter_b() :: binary(). +-type counter_b_op() :: counter_b_anon_op() | counter_b_src_op(). +-type counter_b_anon_op() :: {transfer, {pos_integer(), id(), id()}} | {increment, {pos_integer(), id()}} | {decrement, {pos_integer(), id()}}. --type bcounter_src_op() :: {bcounter_anon_op(), id()}. +-type counter_b_src_op() :: {counter_b_anon_op(), id()}. -opaque id() :: term. %% A replica's identifier. -%% @doc Return a new, empty `bcounter()'. --spec new() -> bcounter(). +%% @doc Return a new, empty `counter_b()'. +-spec new() -> counter_b(). new() -> {orddict:new(), orddict:new()}. -%% @doc Return the available permissions of replica `Id' in a `bcounter()'. --spec localPermissions(id(), bcounter()) -> non_neg_integer(). +%% @doc Return the available permissions of replica `Id' in a `counter_b()'. +-spec localPermissions(id(), counter_b()) -> non_neg_integer(). localPermissions(Id, {P, D}) -> Received = lists:foldl( fun( @@ -88,8 +88,8 @@ localPermissions(Id, {P, D}) -> Received - Granted end. -%% @doc Return the total available permissions in a `bcounter()'. --spec permissions(bcounter()) -> non_neg_integer(). +%% @doc Return the total available permissions in a `counter_b()'. +-spec permissions(counter_b()) -> non_neg_integer(). permissions({P, D}) -> TotalIncrements = orddict:fold( fun @@ -105,8 +105,8 @@ permissions({P, D}) -> end, 0, D), TotalIncrements - TotalDecrements. -%% @doc Return the read value of a given `bcounter()', itself. --spec value(bcounter()) -> bcounter(). +%% @doc Return the read value of a given `counter_b()', itself. +-spec value(counter_b()) -> counter_b(). value(Counter) -> Counter. %% @doc Generate a downstream operation. @@ -114,13 +114,13 @@ value(Counter) -> Counter. %% which specify the operation and amount, or `{transfer, pos_integer(), id()}' %% that additionally specifies the target replica. %% The second parameter is an `actor()' who identifies the source replica, -%% and the third parameter is a `bcounter()' which holds the current snapshot. +%% and the third parameter is a `counter_b()' which holds the current snapshot. %% %% Return a tuple containing the operation and source replica. %% This operation fails and returns `{error, no_permissions}' %% if it tries to consume resources unavailable to the source replica %% (which prevents logging of forbidden attempts). --spec downstream(bcounter_op(), bcounter()) -> {ok, term()} | {error, no_permissions}. +-spec downstream(counter_b_op(), counter_b()) -> {ok, term()} | {error, no_permissions}. downstream({increment, {V, Actor}}, _Counter) when is_integer(V), V > 0 -> {ok, {{increment, V}, Actor}}; downstream({decrement, {V, Actor}}, Counter) when is_integer(V), V > 0 -> @@ -134,11 +134,11 @@ generate_downstream_check(Op, Actor, Counter, V) -> Available < V -> {error, no_permissions} end. -%% @doc Update a `bcounter()' with a downstream operation, +%% @doc Update a `counter_b()' with a downstream operation, %% usually created with `generate_downstream'. %% -%% Return the resulting `bcounter()' after applying the operation. --spec update(term(), bcounter()) -> {ok, bcounter()}. +%% Return the resulting `counter_b()' after applying the operation. +-spec update(term(), counter_b()) -> {ok, counter_b()}. update({{increment, V}, Id}, Counter) -> increment(Id, V, Counter); update({{decrement, V}, Id}, Counter) -> @@ -158,12 +158,12 @@ decrement(Id, V, {P, D}) -> transfer(From, To, V, {P, D}) -> {ok, {orddict:update_counter({From, To}, V, P), D}}. -%% doc Return the binary representation of a `bcounter()'. --spec to_binary(bcounter()) -> binary(). +%% doc Return the binary representation of a `counter_b()'. +-spec to_binary(counter_b()) -> binary(). to_binary(C) -> term_to_binary(C). -%% doc Return a `bcounter()' from its binary representation. --spec from_binary(binary()) -> {ok, bcounter()}. +%% doc Return a `counter_b()' from its binary representation. +-spec from_binary(binary()) -> {ok, counter_b()}. from_binary(<>) -> {ok, binary_to_term(B)}. %% @doc The following operation verifies @@ -199,7 +199,7 @@ apply_op(Op, Counter) -> {ok, NewCounter} = update(OP_DS, Counter), NewCounter. -%% Tests creating a new `bcounter()'. +%% Tests creating a new `counter_b()'. new_test() -> ?assertEqual({[], []}, new()). @@ -271,22 +271,22 @@ transfer_test() -> %% Tests the function `value()'. value_test() -> - %% Test on `bcounter()' resulting from applying all kinds of operation. + %% Test on `counter_b()' resulting from applying all kinds of operation. Counter0 = new(), Counter1 = apply_op({increment, {10, r1}}, Counter0), Counter2 = apply_op({decrement, {6, r1}}, Counter1), Counter3 = apply_op({transfer, {2, r2, r1}}, Counter2), - %% Assert `value()' returns `bcounter()' itself. + %% Assert `value()' returns `counter_b()' itself. ?assertEqual(Counter3, value(Counter3)). %% Tests serialization functions `to_binary()' and `from_binary()'. binary_test() -> - %% Test on `bcounter()' resulting from applying all kinds of operation. + %% Test on `counter_b()' resulting from applying all kinds of operation. Counter0 = new(), Counter1 = apply_op({increment, {10, r1}}, Counter0), Counter2 = apply_op({decrement, {6, r1}}, Counter1), Counter3 = apply_op({transfer, {2, r2, r1}}, Counter2), - %% Assert marshaling and unmarshaling holds the same `bcounter()'. + %% Assert marshaling and unmarshaling holds the same `counter_b()'. B = to_binary(Counter3), ?assertEqual({ok, Counter3}, from_binary(B)). diff --git a/src/antidote_crdt_fat_counter.erl b/src/counter_fat.erl similarity index 97% rename from src/antidote_crdt_fat_counter.erl rename to src/counter_fat.erl index 8fd1ec7..2d2b840 100644 --- a/src/antidote_crdt_fat_counter.erl +++ b/src/counter_fat.erl @@ -18,7 +18,7 @@ %% %% ------------------------------------------------------------------- -%% antidote_crdt_fat_counter: A convergent, replicated, operation based Fat Counter +%% counter_fat: A convergent, replicated, operation based Fat Counter %% The state of this fat counter is list of pairs where each pair is an integer %% and a related token. %% Basically when the counter recieves {increment, N} or {decrement, N} it generates @@ -26,8 +26,9 @@ %% On update, all seen tokens are removed and the new pair is then added to the state. %% This token keeps growing ("Fat" Counter) but it useful as it allows the reset %% functionaility, On reset(), all seen tokens are removed. +%% link to paper: http://haslab.uminho.pt/cbm/files/a3-younes.pdf --module(antidote_crdt_fat_counter). +-module(counter_fat). -behaviour(antidote_crdt). diff --git a/src/antidote_crdt_counter.erl b/src/counter_pn.erl similarity index 90% rename from src/antidote_crdt_counter.erl rename to src/counter_pn.erl index 38c3536..af5bee1 100644 --- a/src/antidote_crdt_counter.erl +++ b/src/counter_pn.erl @@ -18,15 +18,13 @@ %% %% ------------------------------------------------------------------- -%% antidote_crdt_pncounter: A convergent, replicated, operation +%% counter_pn: A convergent, replicated, operation %% based PN-Counter --module(antidote_crdt_counter). +-module(counter_pn). -behaviour(antidote_crdt). --include("antidote_crdt.hrl"). - -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -endif. @@ -43,19 +41,25 @@ require_state_downstream/1 ]). -%% @doc Create a new, empty 'pncounter()' + +-type state() :: integer(). +-type op() :: {increment, integer()} | + {decrement, integer()}. +-type effect() :: integer(). + +%% @doc Create a new, empty 'counter_pn' new() -> 0. -%% @doc Create 'pncounter()' with initial value --spec new(integer()) -> pncounter(). +%% @doc Create 'counter_pn' with initial value +-spec new(integer()) -> state(). new(Value) when is_integer(Value) -> Value; new(_) -> new(). %% @doc The single, total value of a `pncounter()' --spec value(pncounter()) -> integer(). +-spec value(state()) -> integer(). value(PNCnt) when is_integer(PNCnt) -> PNCnt. @@ -63,7 +67,7 @@ value(PNCnt) when is_integer(PNCnt) -> %% The first parameter is either `increment' or `decrement' or the two tuples %% `{increment, pos_integer()}' or `{decrement, pos_integer()}'. The second parameter %% is the pncounter (this parameter is not actually used). --spec downstream(pncounter_update(), pncounter()) -> {ok, pncounter_effect()}. +-spec downstream(op(), state()) -> {ok, effect()}. downstream(increment, _PNCnt) -> {ok, 1}; downstream(decrement, _PNCnt) -> @@ -81,17 +85,17 @@ downstream({decrement, By}, _PNCnt) when is_integer(By) -> %% The 2nd argument is the `pncounter()' to update. %% %% returns the updated `pncounter()' --spec update(pncounter_effect(), pncounter()) -> {ok, pncounter()}. +-spec update(effect(), state()) -> {ok, state()}. update(N, PNCnt) -> {ok, PNCnt + N}. %% @doc Compare if two `pncounter()' are equal. Only returns `true()' if both %% of their positive and negative entries are equal. --spec equal(pncounter(), pncounter()) -> boolean(). +-spec equal(state(), state()) -> boolean(). equal(PNCnt1, PNCnt2) -> PNCnt1 =:= PNCnt2. --spec to_binary(pncounter()) -> binary(). +-spec to_binary(state()) -> binary(). to_binary(PNCounter) -> term_to_binary(PNCounter). diff --git a/src/antidote_crdt_flag_dw.erl b/src/flag_dw.erl similarity index 80% rename from src/antidote_crdt_flag_dw.erl rename to src/flag_dw.erl index 0270052..649d10c 100644 --- a/src/antidote_crdt_flag_dw.erl +++ b/src/flag_dw.erl @@ -22,7 +22,7 @@ %% An operation-based Disable-wins Flag CRDT. %% @end --module(antidote_crdt_flag_dw). +-module(flag_dw). %% Callbacks -export([ new/0, @@ -47,10 +47,10 @@ -define(V1_VERS, 1). -export_type([flag_dw/0]). --opaque flag_dw() :: {antidote_crdt_flag:tokens(), antidote_crdt_flag:tokens()}. +-opaque flag_dw() :: {flag_helper:tokens(), flag_helper:tokens()}. %% SeenTokens, NewEnableTokens, NewDisableTokens --type downstream_op() :: {antidote_crdt_flag:tokens(), antidote_crdt_flag:tokens(), antidote_crdt_flag:tokens()}. +-type downstream_op() :: {flag_helper:tokens(), flag_helper:tokens(), flag_helper:tokens()}. -spec new() -> flag_dw(). new() -> @@ -60,11 +60,11 @@ new() -> value({EnableTokens, DisableTokens}) -> DisableTokens == [] andalso EnableTokens =/= []. --spec downstream(antidote_crdt_flag:op(), flag_dw()) -> {ok, downstream_op()}. +-spec downstream(flag_helper:op(), flag_dw()) -> {ok, downstream_op()}. downstream({disable, {}}, {EnableTokens, DisableTokens}) -> - {ok, {EnableTokens ++ DisableTokens, [], [antidote_crdt_flag:unique()]}}; + {ok, {EnableTokens ++ DisableTokens, [], [flag_helper:unique()]}}; downstream({enable, {}}, {EnableTokens, DisableTokens}) -> - {ok, {EnableTokens ++ DisableTokens, [antidote_crdt_flag:unique()], []}}; + {ok, {EnableTokens ++ DisableTokens, [flag_helper:unique()], []}}; downstream({reset, {}}, {EnableTokens, DisableTokens}) -> {ok, {EnableTokens ++ DisableTokens, [], []}}. @@ -78,7 +78,7 @@ downstream({reset, {}}, {EnableTokens, DisableTokens}) -> equal(Flag1, Flag2) -> Flag1 == Flag2. --spec to_binary(flag_dw()) -> antidote_crdt_flag:binary_flag(). +-spec to_binary(flag_dw()) -> flag_helper:binary_flag(). to_binary(Flag) -> %% @TODO something smarter <>. @@ -87,12 +87,12 @@ from_binary(<>) -> %% @TODO something smarter {ok, binary_to_term(Bin)}. -is_operation(A) -> antidote_crdt_flag:is_operation(A). +is_operation(A) -> flag_helper:is_operation(A). is_bottom(Flag) -> Flag == new(). -require_state_downstream(A) -> antidote_crdt_flag:require_state_downstream(A). +require_state_downstream(A) -> flag_helper:require_state_downstream(A). %% =================================================================== diff --git a/src/antidote_crdt_flag_ew.erl b/src/flag_ew.erl similarity index 85% rename from src/antidote_crdt_flag_ew.erl rename to src/flag_ew.erl index 55a085a..b1e190e 100644 --- a/src/antidote_crdt_flag_ew.erl +++ b/src/flag_ew.erl @@ -22,7 +22,7 @@ %% An operation-based Enable-wins Flag CRDT. %% @end --module(antidote_crdt_flag_ew). +-module(flag_ew). %% Callbacks -export([ new/0, @@ -47,10 +47,10 @@ -define(V1_VERS, 1). -export_type([flag_ew/0]). --opaque flag_ew() :: antidote_crdt_flag:flag(). +-opaque flag_ew() :: flag_helper:flag(). %% SeenTokens, NewTokens --type downstream_op() :: {antidote_crdt_flag:tokens(), antidote_crdt_flag:tokens()}. +-type downstream_op() :: {flag_helper:tokens(), flag_helper:tokens()}. -spec new() -> flag_ew(). new() -> @@ -60,11 +60,11 @@ new() -> value(EnableTokens) -> EnableTokens =/= []. --spec downstream(antidote_crdt_flag:op(), flag_ew()) -> {ok, downstream_op()}. +-spec downstream(flag_helper:op(), flag_ew()) -> {ok, downstream_op()}. downstream({disable, {}}, Tokens) -> {ok, {Tokens, []}}; downstream({enable, {}}, Tokens) -> - {ok, {Tokens, [antidote_crdt_flag:unique()]}}; + {ok, {Tokens, [flag_helper:unique()]}}; downstream({reset, {}}, Tokens) -> {ok, {Tokens, []}}. @@ -77,7 +77,7 @@ downstream({reset, {}}, Tokens) -> equal(Flag1, Flag2) -> Flag1 == Flag2. % Everything inside is ordered, so this should work --spec to_binary(flag_ew()) -> antidote_crdt_flag:binary_flag(). +-spec to_binary(flag_ew()) -> flag_helper:binary_flag(). to_binary(Flag) -> %% @TODO something smarter <>. @@ -86,12 +86,12 @@ from_binary(<>) -> %% @TODO something smarter {ok, binary_to_term(Bin)}. -is_operation(A) -> antidote_crdt_flag:is_operation(A). +is_operation(A) -> flag_helper:is_operation(A). is_bottom(Flag) -> Flag == new(). -require_state_downstream(A) -> antidote_crdt_flag:require_state_downstream(A). +require_state_downstream(A) -> flag_helper:require_state_downstream(A). %% =================================================================== %% EUnit tests diff --git a/src/antidote_crdt_flag.erl b/src/flag_helper.erl similarity index 94% rename from src/antidote_crdt_flag.erl rename to src/flag_helper.erl index 85f122f..25b64d9 100644 --- a/src/antidote_crdt_flag.erl +++ b/src/flag_helper.erl @@ -19,10 +19,10 @@ %% ------------------------------------------------------------------- %% @doc -%% A wrapper for operation-based flags, enable wins flag and disable wins flag. +%% A helper for operation-based flags, enable wins flag and disable wins flag. %% @end --module(antidote_crdt_flag). +-module(flag_helper). %% Callbacks diff --git a/src/antidote_crdt_integer.erl b/src/integer.erl similarity index 97% rename from src/antidote_crdt_integer.erl rename to src/integer.erl index 300fb72..9e1fd27 100644 --- a/src/antidote_crdt_integer.erl +++ b/src/integer.erl @@ -18,7 +18,7 @@ %% %% ------------------------------------------------------------------- -%% antidote_crdt_integer: A convergent, replicated, operation based integer +%% integer: A convergent, replicated, operation based integer %% %% This is an extension of the counter: %% Besides the increment operation, it also provides a set operation @@ -32,7 +32,7 @@ %% Implementation: %% A mix of counter and mvreg --module(antidote_crdt_integer). +-module(integer). -behaviour(antidote_crdt). diff --git a/src/antidote_crdt_map_aw.erl b/src/map_aw.erl similarity index 95% rename from src/antidote_crdt_map_aw.erl rename to src/map_aw.erl index 9207a39..10fb5e2 100644 --- a/src/antidote_crdt_map_aw.erl +++ b/src/map_aw.erl @@ -35,7 +35,7 @@ %% concurrent updates can be reconciled. %% This could be optimized for certain types --module(antidote_crdt_map_aw). +-module(map_aw). -behaviour(antidote_crdt). @@ -200,24 +200,22 @@ distinct([]) -> true; distinct([X|Xs]) -> not lists:member(X, Xs) andalso distinct(Xs). - - - %% =================================================================== %% EUnit tests %% =================================================================== + -ifdef(TEST). reset1_test() -> Set0 = new(), % DC1: a.incr - {ok, Incr1} = downstream({update, {{a, antidote_crdt_integer}, {increment, 1}}}, Set0), + {ok, Incr1} = downstream({update, {{a, integer}, {increment, 1}}}, Set0), {ok, Set1a} = update(Incr1, Set0), % DC1 reset {ok, Reset1} = downstream({reset, {}}, Set1a), {ok, Set1b} = update(Reset1, Set1a), % DC2 a.remove - {ok, Remove1} = downstream({remove, {a, antidote_crdt_integer}}, Set0), + {ok, Remove1} = downstream({remove, {a, integer}}, Set0), {ok, Set2a} = update(Remove1, Set0), % DC2 --> DC1 {ok, Set1c} = update(Remove1, Set1b), @@ -225,18 +223,11 @@ reset1_test() -> {ok, Reset2} = downstream({reset, {}}, Set1c), {ok, Set1d} = update(Reset2, Set1c), % DC1: a.incr - {ok, Incr2} = downstream({update, {{a, antidote_crdt_integer}, {increment, 0}}}, Set1d), + {ok, Incr2} = downstream({update, {{a, integer}, {increment, 0}}}, Set1d), {ok, Set1e} = update(Incr2, Set1d), ?assertEqual([], value(Set2a)), ?assertEqual([], value(Set1d)), - ?assertEqual([{{a, antidote_crdt_integer}, 1}], value(Set1e)). - - - - - --endif. - - + ?assertEqual([{{a, integer}, 1}], value(Set1e)). +-endif. \ No newline at end of file diff --git a/src/antidote_crdt_gmap.erl b/src/map_go.erl similarity index 83% rename from src/antidote_crdt_gmap.erl rename to src/map_go.erl index 98b5dbf..421bc9f 100644 --- a/src/antidote_crdt_gmap.erl +++ b/src/map_go.erl @@ -18,14 +18,14 @@ %% %% ------------------------------------------------------------------- -%% @doc module antidote_crdt_gmap - A grow-only map +%% @doc module map_go - A grow-only map %% %% This map simply forwards all operations to the embedded CRDTs. %% There is no real remove-operation. %% %% The reset operation, forwards the reset to all values in the map. --module(antidote_crdt_gmap). +-module(map_go). -behaviour(antidote_crdt). @@ -38,31 +38,31 @@ -endif. --type gmap() :: dict:dict({Key::term(), Type::atom()}, NestedState::term()). --type gmap_op() :: +-type map_go() :: dict:dict({Key::term(), Type::atom()}, NestedState::term()). +-type map_go_op() :: {update, nested_op()} | {update, [nested_op()]} | {reset, {}}. -type nested_op() :: {{Key::term(), Type::atom() }, Op::term()}. --type gmap_effect() :: +-type map_go_effect() :: {update, nested_downstream()} | {update, [nested_downstream()]}. -type nested_downstream() :: {{Key::term(), Type::atom() }, Op::term()}. --spec new() -> gmap(). +-spec new() -> map_go(). new() -> dict:new(). --spec value(gmap()) -> [{{Key::term(), Type::atom()}, Value::term()}]. +-spec value(map_go()) -> [{{Key::term(), Type::atom()}, Value::term()}]. value(Map) -> lists:sort([{{Key, Type}, Type:value(Value)} || {{Key, Type}, Value} <- dict:to_list(Map)]). --spec require_state_downstream(gmap_op()) -> boolean(). +-spec require_state_downstream(map_go_op()) -> boolean(). require_state_downstream(_Op) -> true. --spec downstream(gmap_op(), gmap()) -> {ok, gmap_effect()}. +-spec downstream(map_go_op(), map_go()) -> {ok, map_go_effect()}. downstream({update, {{Key, Type}, Op}}, CurrentMap) -> % TODO could be optimized for some types CurrentValue = case dict:is_key({Key, Type}, CurrentMap) of @@ -87,7 +87,7 @@ downstream({reset, {}}, CurrentMap) -> DownstreamResets = lists:flatmap(Reset, dict:to_list(CurrentMap)), {ok, {update, DownstreamResets}}. --spec update(gmap_effect(), gmap()) -> {ok, gmap()}. +-spec update(map_go_effect(), map_go()) -> {ok, map_go()}. update({update, {{Key, Type}, Op}}, Map) -> case dict:is_key({Key, Type}, Map) of true -> {ok, dict:update({Key, Type}, fun(V) -> {ok, Value} = Type:update(Op, V), Value end, Map)}; @@ -149,18 +149,18 @@ new_test() -> update_test() -> Map1 = new(), - {ok, DownstreamOp} = downstream({update, {{key1, antidote_crdt_lwwreg}, {assign, <<"test">>}}}, Map1), - ?assertMatch({update, {{key1, antidote_crdt_lwwreg}, {_TS, <<"test">>}}}, DownstreamOp), + {ok, DownstreamOp} = downstream({update, {{key1, register_lww}, {assign, <<"test">>}}}, Map1), + ?assertMatch({update, {{key1, register_lww}, {_TS, <<"test">>}}}, DownstreamOp), {ok, Map2} = update(DownstreamOp, Map1), - ?assertEqual([{{key1, antidote_crdt_lwwreg}, <<"test">>}], value(Map2)). + ?assertEqual([{{key1, register_lww}, <<"test">>}], value(Map2)). update2_test() -> Map1 = new(), - {ok, Effect1} = downstream({update, [{{a, antidote_crdt_orset}, {add, a}}]}, Map1), + {ok, Effect1} = downstream({update, [{{a, set_aw}, {add, a}}]}, Map1), {ok, Map2} = update(Effect1, Map1), {ok, Effect2} = downstream({reset, {}}, Map2), {ok, Map3} = update(Effect2, Map2), - ?assertEqual([{{a, antidote_crdt_orset}, []}], value(Map3)). + ?assertEqual([{{a, set_aw}, []}], value(Map3)). -endif. diff --git a/src/antidote_crdt_map_rr.erl b/src/map_rr.erl similarity index 87% rename from src/antidote_crdt_map_rr.erl rename to src/map_rr.erl index b337374..2d80525 100644 --- a/src/antidote_crdt_map_rr.erl +++ b/src/map_rr.erl @@ -18,7 +18,7 @@ %% %% ------------------------------------------------------------------- -%% @doc module antidote_crdt_map_rr - A CRDT map datatype with a reset functionality +%% @doc module map_rr - A CRDT map datatype with a reset functionality %% %% Inserting a new element in the map: %% if element already there -> do nothing @@ -45,7 +45,7 @@ %% Resetting the map means removing all the current entries %% --module(antidote_crdt_map_rr). +-module(map_rr). -behaviour(antidote_crdt). @@ -241,13 +241,13 @@ is_bottom(Map) -> reset1_test() -> Map0 = new(), % DC1: a.incr - {ok, Incr1} = downstream({update, {{a, antidote_crdt_fat_counter}, {increment, 1}}}, Map0), + {ok, Incr1} = downstream({update, {{a, counter_fat}, {increment, 1}}}, Map0), {ok, Map1a} = update(Incr1, Map0), % DC1 reset {ok, Reset1} = downstream({reset, {}}, Map1a), {ok, Map1b} = update(Reset1, Map1a), % DC2 a.remove - {ok, Remove1} = downstream({remove, {a, antidote_crdt_fat_counter}}, Map0), + {ok, Remove1} = downstream({remove, {a, counter_fat}}, Map0), {ok, Map2a} = update(Remove1, Map0), % DC2 --> DC1 {ok, Map1c} = update(Remove1, Map1b), @@ -255,7 +255,7 @@ reset1_test() -> {ok, Reset2} = downstream({reset, {}}, Map1c), {ok, Map1d} = update(Reset2, Map1c), % DC1: a.incr - {ok, Incr2} = downstream({update, {{a, antidote_crdt_fat_counter}, {increment, 2}}}, Map1d), + {ok, Incr2} = downstream({update, {{a, counter_fat}, {increment, 2}}}, Map1d), {ok, Map1e} = update(Incr2, Map1d), io:format("Map0 = ~p~n", [Map0]), @@ -272,24 +272,24 @@ reset1_test() -> io:format("Map1e = ~p~n", [Map1e]), ?assertEqual([], value(Map0)), - ?assertEqual([{{a, antidote_crdt_fat_counter}, 1}], value(Map1a)), + ?assertEqual([{{a, counter_fat}, 1}], value(Map1a)), ?assertEqual([], value(Map1b)), ?assertEqual([], value(Map2a)), ?assertEqual([], value(Map1c)), ?assertEqual([], value(Map1d)), - ?assertEqual([{{a, antidote_crdt_fat_counter}, 2}], value(Map1e)). + ?assertEqual([{{a, counter_fat}, 2}], value(Map1e)). reset2_test() -> Map0 = new(), % DC1: s.add - {ok, Add1} = downstream({update, {{s, antidote_crdt_set_rw}, {add, a}}}, Map0), + {ok, Add1} = downstream({update, {{s, set_rw}, {add, a}}}, Map0), {ok, Map1a} = update(Add1, Map0), % DC1 reset {ok, Reset1} = downstream({reset, {}}, Map1a), {ok, Map1b} = update(Reset1, Map1a), % DC2 s.remove - {ok, Remove1} = downstream({remove, {s, antidote_crdt_set_rw}}, Map0), + {ok, Remove1} = downstream({remove, {s, set_rw}}, Map0), {ok, Map2a} = update(Remove1, Map0), % DC2 --> DC1 {ok, Map1c} = update(Remove1, Map1b), @@ -297,7 +297,7 @@ reset2_test() -> {ok, Reset2} = downstream({reset, {}}, Map1c), {ok, Map1d} = update(Reset2, Map1c), % DC1: s.add - {ok, Add2} = downstream({update, {{s, antidote_crdt_set_rw}, {add, b}}}, Map1d), + {ok, Add2} = downstream({update, {{s, set_rw}, {add, b}}}, Map1d), {ok, Map1e} = update(Add2, Map1d), io:format("Map0 = ~p~n" , [value(Map0)]), @@ -314,21 +314,21 @@ reset2_test() -> io:format("Map1e = ~p~n" , [value(Map1e)]), ?assertEqual([], value(Map0)), - ?assertEqual([{{s, antidote_crdt_set_rw}, [a]}], value(Map1a)), + ?assertEqual([{{s, set_rw}, [a]}], value(Map1a)), ?assertEqual([], value(Map1b)), ?assertEqual([], value(Map2a)), ?assertEqual([], value(Map1c)), ?assertEqual([], value(Map1d)), - ?assertEqual([{{s, antidote_crdt_set_rw}, [b]}], value(Map1e)). + ?assertEqual([{{s, set_rw}, [b]}], value(Map1e)). prop1_test() -> Map0 = new(), % DC1: s.add - {ok, Add1} = downstream({update, {{a, antidote_crdt_map_rr}, {update, {{a, antidote_crdt_set_rw}, {add, a}}}}}, Map0), + {ok, Add1} = downstream({update, {{a, map_rr}, {update, {{a, set_rw}, {add, a}}}}}, Map0), {ok, Map1a} = update(Add1, Map0), % DC1 reset - {ok, Reset1} = downstream({remove, {a, antidote_crdt_map_rr}}, Map1a), + {ok, Reset1} = downstream({remove, {a, map_rr}}, Map1a), {ok, Map1b} = update(Reset1, Map1a), io:format("Map0 = ~p~n", [Map0]), @@ -338,17 +338,17 @@ prop1_test() -> io:format("Map1b = ~p~n", [Map1b]), ?assertEqual([], value(Map0)), - ?assertEqual([{{a, antidote_crdt_map_rr}, [{{a, antidote_crdt_set_rw}, [a]}]}], value(Map1a)), + ?assertEqual([{{a, map_rr}, [{{a, set_rw}, [a]}]}], value(Map1a)), ?assertEqual([], value(Map1b)). prop2_test() -> Map0 = new(), % DC1: update remove - {ok, Add1} = downstream({update, [{{b, antidote_crdt_map_rr}, {remove, {a, antidote_crdt_set_rw}}}]}, Map0), + {ok, Add1} = downstream({update, [{{b, map_rr}, {remove, {a, set_rw}}}]}, Map0), {ok, Map1a} = update(Add1, Map0), % DC2 remove - {ok, Remove2} = downstream({remove, {b, antidote_crdt_map_rr}}, Map0), + {ok, Remove2} = downstream({remove, {b, map_rr}}, Map0), {ok, Map2a} = update(Remove2, Map0), % pull DC2 -> DC1 @@ -375,14 +375,14 @@ remove_test() -> ?assertEqual([], value(M1)), ?assertEqual(true, is_bottom(M1)), M2 = upd({update, [ - {{<<"a">>, antidote_crdt_orset}, {add, <<"1">>}}, - {{<<"b">>, antidote_crdt_mvreg}, {assign, <<"2">>}}, - {{<<"c">>, antidote_crdt_fat_counter}, {increment, 1}} + {{<<"a">>, set_aw}, {add, <<"1">>}}, + {{<<"b">>, register_mv}, {assign, <<"2">>}}, + {{<<"c">>, counter_fat}, {increment, 1}} ]}, M1), ?assertEqual([ - {{<<"a">>, antidote_crdt_orset}, [<<"1">>]}, - {{<<"b">>, antidote_crdt_mvreg}, [<<"2">>]}, - {{<<"c">>, antidote_crdt_fat_counter}, 1} + {{<<"a">>, set_aw}, [<<"1">>]}, + {{<<"b">>, register_mv}, [<<"2">>]}, + {{<<"c">>, counter_fat}, 1} ], value(M2)), ?assertEqual(false, is_bottom(M2)), M3 = upd({reset, {}}, M2), @@ -391,4 +391,4 @@ remove_test() -> ?assertEqual(true, is_bottom(M3)), ok. --endif. +-endif. \ No newline at end of file diff --git a/src/antidote_crdt_lwwreg.erl b/src/register_lww.erl similarity index 86% rename from src/antidote_crdt_lwwreg.erl rename to src/register_lww.erl index caa4a8b..67e2a5f 100644 --- a/src/antidote_crdt_lwwreg.erl +++ b/src/register_lww.erl @@ -18,13 +18,13 @@ %% %% ------------------------------------------------------------------- -%% @doc module antidote_crdt_lwwreg - An operation based last-writer-wins register +%% @doc module register_lww - An operation based last-writer-wins register %% Each operation is assigned a timestamp, which is guaranteed to be greater than %% the current timestamp. %% The current value of the register is the value assigned with the greatest timestamp %% or the empty binary if there was no assignment yet. --module(antidote_crdt_lwwreg). +-module(register_lww). -behaviour(antidote_crdt). @@ -43,11 +43,11 @@ require_state_downstream/1 ]). --export_type([lwwreg/0, lwwreg_op/0]). +-export_type([register_lww/0, register_lww_op/0]). --opaque lwwreg() :: {non_neg_integer(), term()}. +-opaque register_lww() :: {non_neg_integer(), term()}. --type lwwreg_op() :: {assign, term(), non_neg_integer()} | {assign, term()}. +-type register_lww_op() :: {assign, term(), non_neg_integer()} | {assign, term()}. new() -> {0, <<>>}. @@ -55,7 +55,7 @@ new() -> value({_Time, Val}) -> Val. --spec downstream(lwwreg_op(), lwwreg()) -> {ok, term()}. +-spec downstream(register_lww_op(), register_lww()) -> {ok, term()}. downstream({assign, Value, Time}, {OldTime, _OldValue}) -> {ok, {max(Time, OldTime + 1), Value}}; downstream({assign, Value}, State) -> diff --git a/src/antidote_crdt_mvreg.erl b/src/register_mv.erl similarity index 82% rename from src/antidote_crdt_mvreg.erl rename to src/register_mv.erl index b7efbc0..774d2db 100644 --- a/src/antidote_crdt_mvreg.erl +++ b/src/register_mv.erl @@ -1,6 +1,6 @@ %% ------------------------------------------------------------------- %% -%% riak_dt_mvreg: A DVVSet based multi value register +%% riak_dt_register_mv: A DVVSet based multi value register %% %% Copyright (c) 2007-2013 Basho Technologies, Inc. All Rights Reserved. %% @@ -31,7 +31,7 @@ %% %% @end --module(antidote_crdt_mvreg). +-module(register_mv). -behaviour(antidote_crdt). @@ -53,34 +53,34 @@ -include_lib("eunit/include/eunit.hrl"). -endif. --export_type([mvreg/0, mvreg_op/0]). +-export_type([register_mv/0, register_mv_op/0]). %% TODO: make opaque --type mvreg() :: [{term(), uniqueToken()}]. +-type register_mv() :: [{term(), uniqueToken()}]. -type uniqueToken() :: term(). --type mvreg_effect() :: +-type register_mv_effect() :: {Value::term(), uniqueToken(), Overridden::[uniqueToken()]} | {reset, Overridden::[uniqueToken()]}. --type mvreg_op() :: {assign, term()}. +-type register_mv_op() :: {assign, term()}. -%% @doc Create a new, empty `mvreg()' --spec new() -> mvreg(). +%% @doc Create a new, empty `register_mv()' +-spec new() -> register_mv(). new() -> []. -%% @doc The values of this `mvreg()'. Multiple values can be returned, +%% @doc The values of this `register_mv()'. Multiple values can be returned, %% since there can be diverged value in this register. --spec value(mvreg()) -> [term()]. +-spec value(register_mv()) -> [term()]. value(MVReg) -> [V || {V, _} <- MVReg]. --spec downstream(mvreg_op(), mvreg()) -> {ok, mvreg_effect()}. +-spec downstream(register_mv_op(), register_mv()) -> {ok, register_mv_effect()}. downstream({assign, Value}, MVReg) -> Token = unique(), Overridden = [Tok || {_, Tok} <- MVReg], @@ -94,7 +94,7 @@ unique() -> crypto:strong_rand_bytes(20). --spec update(mvreg_effect(), mvreg()) -> {ok, mvreg()}. +-spec update(register_mv_effect(), register_mv()) -> {ok, register_mv()}. update({Value, Token, Overridden}, MVreg) -> % remove overridden values MVreg2 = [{V, T} || {V, T} <- MVreg, not lists:member(T, Overridden)], @@ -110,19 +110,19 @@ insert_sorted(A, [X|Xs]) when A < X -> [A, X|Xs]; insert_sorted(A, [X|Xs]) -> [X|insert_sorted(A, Xs)]. --spec equal(mvreg(), mvreg()) -> boolean(). +-spec equal(register_mv(), register_mv()) -> boolean(). equal(MVReg1, MVReg2) -> MVReg1 == MVReg2. -define(TAG, 85). -define(V1_VERS, 1). --spec to_binary(mvreg()) -> binary(). +-spec to_binary(register_mv()) -> binary(). to_binary(MVReg) -> <>. -%% @doc Decode binary `mvreg()' --spec from_binary(binary()) -> {ok, mvreg()} | {error, term()}. +%% @doc Decode binary `register_mv()' +-spec from_binary(binary()) -> {ok, register_mv()} | {error, term()}. from_binary(<>) -> {ok, riak_dt:from_binary(Bin)}. diff --git a/src/antidote_crdt_rga.erl b/src/rga.erl similarity index 99% rename from src/antidote_crdt_rga.erl rename to src/rga.erl index 14186f2..e89efb4 100644 --- a/src/antidote_crdt_rga.erl +++ b/src/rga.erl @@ -35,7 +35,7 @@ %% Convergent and Commutative Replicated Data Types. http://hal.upmc.fr/inria-00555588/ %% %% @end --module(antidote_crdt_rga). +-module(rga). -behaviour(antidote_crdt). diff --git a/src/antidote_crdt_orset.erl b/src/set_aw.erl similarity index 77% rename from src/antidote_crdt_orset.erl rename to src/set_aw.erl index 69ede98..884619b 100644 --- a/src/antidote_crdt_orset.erl +++ b/src/set_aw.erl @@ -1,6 +1,6 @@ %% ------------------------------------------------------------------- %% -%% crdt_orset: A convergent, replicated, operation based observe remove set +%% crdt_set_aw: A convergent, replicated, operation based observe remove set %% %% Copyright (c) 2007-2012 Basho Technologies, Inc. All Rights Reserved. %% @@ -31,7 +31,7 @@ %% remove_all that removes a list of elements from the set; update, that contains %% a list of previous four commands. %% -%% This file is adapted from riak_dt_orset, a state-based implementation of +%% This file is adapted from riak_dt_set_aw, a state-based implementation of %% Observed-Remove Set. %% The changes are as follows: %% 1. `generate_downstream/3' is added, as this is necessary for op-based CRDTs. @@ -42,7 +42,7 @@ %% Convergent and Commutative Replicated Data Types. http://hal.upmc.fr/inria-00555588/ %% %% @end --module(antidote_crdt_orset). +-module(set_aw). -include("antidote_crdt.hrl"). @@ -65,12 +65,12 @@ -include_lib("eunit/include/eunit.hrl"). -endif. --export_type([orset/0, binary_orset/0, orset_op/0]). --opaque orset() :: orddict:orddict(member(), tokens()). +-export_type([set_aw/0, binary_set_aw/0, set_aw_op/0]). +-opaque set_aw() :: orddict:orddict(member(), tokens()). --type binary_orset() :: binary(). %% A binary that from_binary/1 will operate on. +-type binary_set_aw() :: binary(). %% A binary that from_binary/1 will operate on. --type orset_op() :: +-type set_aw_op() :: {add, member()} | {remove, member()} | {add_all, [member()]} @@ -88,60 +88,60 @@ -type token() :: binary(). -type tokens() :: [token()]. --spec new() -> orset(). +-spec new() -> set_aw(). new() -> orddict:new(). -%% @doc return all existing elements in the `orset()'. --spec value(orset()) -> [member()]. -value(ORSet) -> - orddict:fetch_keys(ORSet). +%% @doc return all existing elements in the `set_aw()'. +-spec value(set_aw()) -> [member()]. +value(Set_aw) -> + orddict:fetch_keys(Set_aw). %% @doc generate downstream operations. %% If the operation is add or add_all, generate unique tokens for %% each element and fetches the current supporting tokens. %% If the operation is remove or remove_all, fetches current -%% supporting tokens of these elements existing in the `orset()'. --spec downstream(orset_op(), orset()) -> {ok, downstream_op()}. -downstream({add, Elem}, ORSet) -> - downstream({add_all, [Elem]}, ORSet); -downstream({add_all, Elems}, ORSet) -> +%% supporting tokens of these elements existing in the `set_aw()'. +-spec downstream(set_aw_op(), set_aw()) -> {ok, downstream_op()}. +downstream({add, Elem}, Set_aw) -> + downstream({add_all, [Elem]}, Set_aw); +downstream({add_all, Elems}, Set_aw) -> CreateDownstream = fun(Elem, CurrentTokens) -> Token = unique(), {Elem, [Token], CurrentTokens} end, - DownstreamOps = create_downstreams(CreateDownstream, lists:usort(Elems), ORSet, []), + DownstreamOps = create_downstreams(CreateDownstream, lists:usort(Elems), Set_aw, []), {ok, lists:reverse(DownstreamOps)}; -downstream({remove, Elem}, ORSet) -> - downstream({remove_all, [Elem]}, ORSet); -downstream({remove_all, Elems}, ORSet) -> +downstream({remove, Elem}, Set_aw) -> + downstream({remove_all, [Elem]}, Set_aw); +downstream({remove_all, Elems}, Set_aw) -> CreateDownstream = fun(Elem, CurrentTokens) -> {Elem, [], CurrentTokens} end, - DownstreamOps = create_downstreams(CreateDownstream, lists:usort(Elems), ORSet, []), + DownstreamOps = create_downstreams(CreateDownstream, lists:usort(Elems), Set_aw, []), {ok, lists:reverse(DownstreamOps)}; -downstream({reset, {}}, ORSet) -> +downstream({reset, {}}, Set_aw) -> % reset is like removing all elements - downstream({remove_all, value(ORSet)}, ORSet). + downstream({remove_all, value(Set_aw)}, Set_aw). -%% @doc apply downstream operations and update an `orset()'. --spec update(downstream_op(), orset()) -> {ok, orset()}. -update(DownstreamOp, ORSet) -> - {ok, apply_downstreams(DownstreamOp, ORSet)}. +%% @doc apply downstream operations and update an `set_aw()'. +-spec update(downstream_op(), set_aw()) -> {ok, set_aw()}. +update(DownstreamOp, Set_aw) -> + {ok, apply_downstreams(DownstreamOp, Set_aw)}. --spec equal(orset(), orset()) -> boolean(). -equal(ORSetA, ORSetB) -> +-spec equal(set_aw(), set_aw()) -> boolean(). +equal(Set_awA, Set_awB) -> % Everything inside is ordered, so this should work - ORSetA == ORSetB. + Set_awA == Set_awB. -include_lib("riak_dt/include/riak_dt_tags.hrl"). -define(TAG, ?DT_ORSET_TAG). -define(V1_VERS, 1). --spec to_binary(orset()) -> binary_orset(). -to_binary(ORSet) -> +-spec to_binary(set_aw()) -> binary_set_aw(). +to_binary(Set_aw) -> %% @TODO something smarter - <>. + <>. from_binary(<>) -> %% @TODO something smarter @@ -153,7 +153,7 @@ unique() -> crypto:strong_rand_bytes(20). %% @private generic downstream op creation for adds and removals -create_downstreams(_CreateDownstream, [], _ORSet, DownstreamOps) -> +create_downstreams(_CreateDownstream, [], _Set_aw, DownstreamOps) -> DownstreamOps; create_downstreams(CreateDownstream, Elems, [], DownstreamOps) -> lists:foldl( @@ -164,37 +164,37 @@ create_downstreams(CreateDownstream, Elems, [], DownstreamOps) -> DownstreamOps, Elems ); -create_downstreams(CreateDownstream, [Elem1|ElemsRest]=Elems, [{Elem2, Tokens}|ORSetRest]=ORSet, DownstreamOps) -> +create_downstreams(CreateDownstream, [Elem1|ElemsRest]=Elems, [{Elem2, Tokens}|Set_awRest]=Set_aw, DownstreamOps) -> if Elem1 == Elem2 -> DownstreamOp = CreateDownstream(Elem1, Tokens), - create_downstreams(CreateDownstream, ElemsRest, ORSetRest, [DownstreamOp|DownstreamOps]); + create_downstreams(CreateDownstream, ElemsRest, Set_awRest, [DownstreamOp|DownstreamOps]); Elem1 > Elem2 -> - create_downstreams(CreateDownstream, Elems, ORSetRest, DownstreamOps); + create_downstreams(CreateDownstream, Elems, Set_awRest, DownstreamOps); true -> DownstreamOp = CreateDownstream(Elem1, Tokens), - create_downstreams(CreateDownstream, ElemsRest, ORSet, [DownstreamOp|DownstreamOps]) + create_downstreams(CreateDownstream, ElemsRest, Set_aw, [DownstreamOp|DownstreamOps]) end. -%% @private apply a list of downstream ops to a given orset -apply_downstreams([], ORSet) -> - ORSet; +%% @private apply a list of downstream ops to a given set_aw +apply_downstreams([], Set_aw) -> + Set_aw; apply_downstreams(Ops, []) -> lists:foldl( - fun({Elem, ToAdd, ToRemove}, ORSet) -> - ORSet ++ apply_downstream(Elem, [], ToAdd, ToRemove) + fun({Elem, ToAdd, ToRemove}, Set_aw) -> + Set_aw ++ apply_downstream(Elem, [], ToAdd, ToRemove) end, [], Ops ); -apply_downstreams([{Elem1, ToAdd, ToRemove}|OpsRest]=Ops, [{Elem2, CurrentTokens}|ORSetRest]=ORSet) -> +apply_downstreams([{Elem1, ToAdd, ToRemove}|OpsRest]=Ops, [{Elem2, CurrentTokens}|Set_awRest]=Set_aw) -> if Elem1 == Elem2 -> - apply_downstream(Elem1, CurrentTokens, ToAdd, ToRemove) ++ apply_downstreams(OpsRest, ORSetRest); + apply_downstream(Elem1, CurrentTokens, ToAdd, ToRemove) ++ apply_downstreams(OpsRest, Set_awRest); Elem1 > Elem2 -> - [{Elem2, CurrentTokens} | apply_downstreams(Ops, ORSetRest)]; + [{Elem2, CurrentTokens} | apply_downstreams(Ops, Set_awRest)]; true -> - apply_downstream(Elem1, [], ToAdd, ToRemove) ++ apply_downstreams(OpsRest, ORSet) + apply_downstream(Elem1, [], ToAdd, ToRemove) ++ apply_downstreams(OpsRest, Set_aw) end. %% @private create an orddict entry from a downstream op @@ -325,15 +325,15 @@ concurrent_add_test() -> ?assertEqual([], value(Set5)). binary_test() -> - ORSet1 = new(), - BinaryORSet1 = to_binary(ORSet1), - {ok, ORSet2} = from_binary(BinaryORSet1), - ?assert(equal(ORSet1, ORSet2)), - - {ok, Op1} = downstream({add, <<"foo">>}, ORSet1), - {ok, ORSet3} = update(Op1, ORSet1), - BinaryORSet3 = to_binary(ORSet3), - {ok, ORSet4} = from_binary(BinaryORSet3), - ?assert(equal(ORSet3, ORSet4)). + Set_aw1 = new(), + BinarySet_aw1 = to_binary(Set_aw1), + {ok, Set_aw2} = from_binary(BinarySet_aw1), + ?assert(equal(Set_aw1, Set_aw2)), + + {ok, Op1} = downstream({add, <<"foo">>}, Set_aw1), + {ok, Set_aw3} = update(Op1, Set_aw1), + BinarySet_aw3 = to_binary(Set_aw3), + {ok, Set_aw4} = from_binary(BinarySet_aw3), + ?assert(equal(Set_aw3, Set_aw4)). -endif. diff --git a/src/antidote_crdt_gset.erl b/src/set_go.erl similarity index 85% rename from src/antidote_crdt_gset.erl rename to src/set_go.erl index dad3df6..455e80b 100644 --- a/src/antidote_crdt_gset.erl +++ b/src/set_go.erl @@ -18,9 +18,9 @@ %% %% ------------------------------------------------------------------- -%% @doc module antidote_crdt_gset - An operation based grow-only set +%% @doc module set_go - An operation based grow-only set --module(antidote_crdt_gset). +-module(set_go). -behaviour(antidote_crdt). @@ -39,11 +39,11 @@ require_state_downstream/1 ]). --type gset() :: ordsets:ordset(member()). --type gset_op() :: {add, member()} +-type set_go() :: ordsets:ordset(member()). +-type set_go_op() :: {add, member()} | {add_all, [member()]}. --type gset_effect() :: gset(). +-type set_go_effect() :: set_go(). -type member() :: term(). new() -> @@ -52,7 +52,7 @@ new() -> value(Set) -> Set. --spec downstream(gset_op(), gset()) -> {ok, gset_effect()}. +-spec downstream(set_go_op(), set_go()) -> {ok, set_go_effect()}. downstream({add, Elem}, _State) -> {ok, ordsets:from_list([Elem])}; downstream({add_all, Elems}, _State) -> @@ -81,6 +81,6 @@ all_test() -> S0 = new(), {ok, Downstream} = downstream({add, a}, S0), {ok, S1} = update(Downstream, S0), - ?assertEqual(1, riak_dt_gset:stat(element_count, S1)). + ?assertEqual(1, riak_dt_set_go:stat(element_count, S1)). -endif. diff --git a/src/antidote_crdt_set_rw.erl b/src/set_rw.erl similarity index 95% rename from src/antidote_crdt_set_rw.erl rename to src/set_rw.erl index 55c2b49..ff0df73 100644 --- a/src/antidote_crdt_set_rw.erl +++ b/src/set_rw.erl @@ -42,7 +42,7 @@ %% (i.e. AddTokens == [] and RemoveTokens == []) %% @end --module(antidote_crdt_set_rw). +-module(set_rw). %% Callbacks @@ -65,12 +65,12 @@ -include_lib("eunit/include/eunit.hrl"). -endif. --export_type([set/0, binary_set/0, set_op/0]). --opaque set() :: orddict:orddict(term(), {tokens(), tokens()}). +-export_type([set_rw/0, binary_set_rw/0, set_rw_op/0]). +-opaque set_rw() :: orddict:orddict(term(), {tokens(), tokens()}). --type binary_set() :: binary(). %% A binary that from_binary/1 will operate on. +-type binary_set_rw() :: binary(). %% A binary that from_binary/1 will operate on. --type set_op() :: +-type set_rw_op() :: {add, member()} | {remove, member()} | {add_all, [member()]} @@ -84,15 +84,15 @@ -type token() :: term(). -type tokens() :: [token()]. --spec new() -> set(). +-spec new() -> set_rw(). new() -> orddict:new(). --spec value(set()) -> [member()]. +-spec value(set_rw()) -> [member()]. value(RWSet) -> [Elem || {Elem, {_, []}} <- RWSet]. --spec downstream(set_op(), set()) -> {ok, downstream_op()}. +-spec downstream(set_rw_op(), set_rw()) -> {ok, downstream_op()}. downstream({add, Elem}, RWSet) -> downstream({add_all, [Elem]}, RWSet); downstream({add_all, Elems}, RWSet) -> @@ -146,7 +146,7 @@ create_downstreams(CreateDownstream, [Elem1|ElemsRest]=Elems, [{Elem2, {AddToken unique() -> crypto:strong_rand_bytes(20). --spec update(downstream_op(), set()) -> {ok, set()}. +-spec update(downstream_op(), set_rw()) -> {ok, set_rw()}. update(DownstreamOp, RWSet) -> RWSet1 = apply_downstreams(DownstreamOp, RWSet), RWSet2 = [Entry || {_, {AddTokens, RemoveTokens}} = Entry <- RWSet1, AddTokens =/= [] orelse RemoveTokens =/= []], @@ -175,14 +175,14 @@ apply_downstream(Elem, SeenTokens, ToAdd, ToRemove, CurrentAddTokens, CurrentRem --spec equal(set(), set()) -> boolean(). +-spec equal(set_rw(), set_rw()) -> boolean(). equal(ORDictA, ORDictB) -> ORDictA == ORDictB. % Everything inside is ordered, so this should work -define(TAG, 77). -define(V1_VERS, 1). --spec to_binary(set()) -> binary_set(). +-spec to_binary(set_rw()) -> binary_set_rw(). to_binary(Set) -> %% @TODO something smarter <>. diff --git a/test/prop_crdt_fat_counter.erl b/test/prop_counter_fat.erl similarity index 79% rename from test/prop_crdt_fat_counter.erl rename to test/prop_counter_fat.erl index b8f3bea..7f328ec 100644 --- a/test/prop_crdt_fat_counter.erl +++ b/test/prop_counter_fat.erl @@ -18,26 +18,26 @@ %% %% ------------------------------------------------------------------- --module(prop_crdt_fat_counter). +-module(prop_counter_fat). -define(PROPER_NO_TRANS, true). -include_lib("proper/include/proper.hrl"). %% API --export([prop_fat_counter_spec/0, fat_counter_op/0, fat_counter_spec/1]). +-export([prop_counter_fat_spec/0, op/0, spec/1]). -prop_fat_counter_spec() -> - crdt_properties:crdt_satisfies_spec(antidote_crdt_fat_counter, fun fat_counter_op/0, fun fat_counter_spec/1). +prop_counter_fat_spec() -> + crdt_properties:crdt_satisfies_spec(counter_fat, fun op/0, fun spec/1). -fat_counter_spec(Operations1) -> +spec(Operations1) -> Operations = crdt_properties:filter_resets(Operations1), lists:sum([X || {_, {increment, X}} <- Operations]) - lists:sum([X || {_, {decrement, X}} <- Operations]). % generates a random counter operation -fat_counter_op() -> +op() -> oneof([ {increment, integer()}, {decrement, integer()}, diff --git a/test/prop_crdt_counter.erl b/test/prop_counter_pn.erl similarity index 82% rename from test/prop_crdt_counter.erl rename to test/prop_counter_pn.erl index 39a56ae..7a2d7a7 100644 --- a/test/prop_crdt_counter.erl +++ b/test/prop_counter_pn.erl @@ -18,27 +18,27 @@ %% %% ------------------------------------------------------------------- --module(prop_crdt_counter). +-module(prop_counter_pn). -define(PROPER_NO_TRANS, true). -include_lib("proper/include/proper.hrl"). %% API --export([prop_counter_spec/0, counter_op/0, counter_spec/1]). +-export([prop_counter_pn_spec/0, op/0, spec/1]). -prop_counter_spec() -> - crdt_properties:crdt_satisfies_spec(antidote_crdt_counter, fun counter_op/0, fun counter_spec/1). +prop_counter_pn_spec() -> + crdt_properties:crdt_satisfies_spec(counter_pn, fun op/0, fun spec/1). -counter_spec(Operations) -> +spec(Operations) -> lists:sum([X || {_, {increment, X}} <- Operations]) + lists:sum([1 || {_, increment} <- Operations]) - lists:sum([X || {_, {decrement, X}} <- Operations]) - lists:sum([1 || {_, decrement} <- Operations]). % generates a random counter operation -counter_op() -> +op() -> oneof([ increment, decrement, diff --git a/test/prop_crdt_flag_dw.erl b/test/prop_flag_dw.erl similarity index 92% rename from test/prop_crdt_flag_dw.erl rename to test/prop_flag_dw.erl index 0420cbf..d3de5a0 100644 --- a/test/prop_crdt_flag_dw.erl +++ b/test/prop_flag_dw.erl @@ -18,7 +18,7 @@ %% %% ------------------------------------------------------------------- --module(prop_crdt_flag_dw). +-module(prop_flag_dw). -define(PROPER_NO_TRANS, true). -include_lib("proper/include/proper.hrl"). @@ -27,7 +27,7 @@ -export([prop_flag_dw_spec/0, op/0, spec/1]). prop_flag_dw_spec() -> - crdt_properties:crdt_satisfies_spec(antidote_crdt_flag_dw, fun op/0, fun spec/1). + crdt_properties:crdt_satisfies_spec(flag_dw, fun op/0, fun spec/1). spec(Operations) -> diff --git a/test/prop_crdt_flag_ew.erl b/test/prop_flag_ew.erl similarity index 92% rename from test/prop_crdt_flag_ew.erl rename to test/prop_flag_ew.erl index a6a68bf..6e59a1b 100644 --- a/test/prop_crdt_flag_ew.erl +++ b/test/prop_flag_ew.erl @@ -18,7 +18,7 @@ %% %% ------------------------------------------------------------------- --module(prop_crdt_flag_ew). +-module(prop_flag_ew). -define(PROPER_NO_TRANS, true). -include_lib("proper/include/proper.hrl"). @@ -27,7 +27,7 @@ -export([prop_flag_ew_spec/0, op/0, spec/1]). prop_flag_ew_spec() -> - crdt_properties:crdt_satisfies_spec(antidote_crdt_flag_ew, fun op/0, fun spec/1). + crdt_properties:crdt_satisfies_spec(flag_ew, fun op/0, fun spec/1). spec(Operations) -> diff --git a/test/prop_crdt_integer.erl b/test/prop_integer.erl similarity index 90% rename from test/prop_crdt_integer.erl rename to test/prop_integer.erl index 069f44f..dd43c15 100644 --- a/test/prop_crdt_integer.erl +++ b/test/prop_integer.erl @@ -18,17 +18,17 @@ %% %% ------------------------------------------------------------------- --module(prop_crdt_integer). +-module(prop_integer). -define(PROPER_NO_TRANS, true). -include_lib("proper/include/proper.hrl"). %% API --export([prop_counter_spec/0, op/0, spec/1]). +-export([prop_integer_spec/0, op/0, spec/1]). -prop_counter_spec() -> - crdt_properties:crdt_satisfies_spec(antidote_crdt_integer, fun op/0, fun spec/1). +prop_integer_spec() -> + crdt_properties:crdt_satisfies_spec(integer, fun op/0, fun spec/1). spec(Operations1) -> diff --git a/test/prop_crdt_map_aw.erl b/test/prop_map_aw.erl similarity index 84% rename from test/prop_crdt_map_aw.erl rename to test/prop_map_aw.erl index ed3bb77..08bf6c6 100644 --- a/test/prop_crdt_map_aw.erl +++ b/test/prop_map_aw.erl @@ -18,17 +18,17 @@ %% %% ------------------------------------------------------------------- --module(prop_crdt_map_aw). +-module(prop_map_aw). -define(PROPER_NO_TRANS, true). -include_lib("proper/include/proper.hrl"). %% API --export([prop_map_spec/0]). +-export([prop_map_aw_spec/0]). -prop_map_spec() -> - crdt_properties:crdt_satisfies_spec(antidote_crdt_map_aw, fun op/0, fun spec/1). +prop_map_aw_spec() -> + crdt_properties:crdt_satisfies_spec(map_aw, fun op/0, fun spec/1). spec(Operations1) -> @@ -54,9 +54,9 @@ nestedOps(Operations, {_,Type}=Key) -> end, Resets ++ [{Clock, NestedOp} || {Clock, {update, {Key2, NestedOp}}} <- Operations, Key == Key2]. -nestedSpec(antidote_crdt_map_aw, Ops) -> spec(Ops); -nestedSpec(antidote_crdt_orset, Ops) -> prop_crdt_orset:add_wins_set_spec(Ops); -nestedSpec(antidote_crdt_integer, Ops) -> prop_crdt_integer:spec(Ops). +nestedSpec(map_aw, Ops) -> spec(Ops); +nestedSpec(set_aw, Ops) -> prop_set_aw:spec(Ops); +nestedSpec(integer, Ops) -> prop_integer:spec(Ops). % normalizes operations (update-lists into single update-operations) normalizeOp({Clock, {update, List}}, _) when is_list(List) -> @@ -102,13 +102,13 @@ removeDuplicateKeys([{Key,Op}|Rest], Keys) -> nestedOp(Size) -> oneof( [ - {{key(), antidote_crdt_integer}, prop_crdt_integer:op()}, - {{key(), antidote_crdt_orset}, prop_crdt_orset:set_op()} + {{key(), integer}, prop_integer:op()}, + {{key(), set_aw}, prop_set_aw:op()} ] ++ if Size > 1 -> - [{{key(), antidote_crdt_map_aw}, ?LAZY(op(Size div 2))}]; + [{{key(), map_aw}, ?LAZY(op(Size div 2))}]; true -> [] end ). @@ -116,12 +116,7 @@ nestedOp(Size) -> typed_key() -> {key(), crdt_type()}. crdt_type() -> - oneof([antidote_crdt_integer, antidote_crdt_orset, antidote_crdt_map_aw]). + oneof([integer, set_aw, map_aw]). key() -> - oneof([a,b,c,d]). - - - - - + oneof([a,b,c,d]). \ No newline at end of file diff --git a/test/prop_crdt_gmap.erl b/test/prop_map_go.erl similarity index 80% rename from test/prop_crdt_gmap.erl rename to test/prop_map_go.erl index 5c3d5fe..c553dc5 100644 --- a/test/prop_crdt_gmap.erl +++ b/test/prop_map_go.erl @@ -18,17 +18,17 @@ %% %% ------------------------------------------------------------------- --module(prop_crdt_gmap). +-module(prop_map_go). -define(PROPER_NO_TRANS, true). -include_lib("proper/include/proper.hrl"). %% API --export([prop_gmap_spec/0]). +-export([prop_map_go_spec/0]). -prop_gmap_spec() -> - crdt_properties:crdt_satisfies_spec(antidote_crdt_gmap, fun op/0, fun spec/1). +prop_map_go_spec() -> + crdt_properties:crdt_satisfies_spec(map_go, fun op/0, fun spec/1). spec(Operations1) -> @@ -47,9 +47,9 @@ nestedOps(Operations, {_,Type}=Key) -> end, Resets ++ [{Clock, NestedOp} || {Clock, {update, {Key2, NestedOp}}} <- Operations, Key == Key2]. -nestedSpec(antidote_crdt_gmap, Ops) -> spec(Ops); -nestedSpec(antidote_crdt_orset, Ops) -> prop_crdt_orset:add_wins_set_spec(Ops); -nestedSpec(antidote_crdt_counter, Ops) -> prop_crdt_counter:counter_spec(Ops). +nestedSpec(map_go, Ops) -> spec(Ops); +nestedSpec(set_aw, Ops) -> prop_set_aw:spec(Ops); +nestedSpec(counter_pn, Ops) -> prop_counter_pn:spec(Ops). normalizeOp({Clock, {update, List}}) when is_list(List) -> @@ -81,22 +81,17 @@ nestedOp(Size) -> [ % TODO add other type (orset) and recursive maps % TODO make sure that keys are unique here and in the is_operation check - {{key(), antidote_crdt_orset}, prop_crdt_orset:set_op()}, - {{key(), antidote_crdt_counter}, prop_crdt_counter:counter_op()} + {{key(), set_aw}, prop_set_aw:op()}, + {{key(), counter_pn}, prop_counter_pn:op()} ] ++ if Size > 1 -> - [{{key(), antidote_crdt_gmap}, ?LAZY(op(Size div 2))}]; + [{{key(), map_go}, ?LAZY(op(Size div 2))}]; true -> [] end ). key() -> - oneof([a,b,c,d]). - - - - - + oneof([a,b,c,d]). \ No newline at end of file diff --git a/test/prop_crdt_map_rr.erl b/test/prop_map_rr.erl similarity index 79% rename from test/prop_crdt_map_rr.erl rename to test/prop_map_rr.erl index 6b0929a..bd069de 100644 --- a/test/prop_crdt_map_rr.erl +++ b/test/prop_map_rr.erl @@ -18,16 +18,16 @@ %% %% ------------------------------------------------------------------- --module(prop_crdt_map_rr). +-module(prop_map_rr). -define(PROPER_NO_TRANS, true). -include_lib("proper/include/proper.hrl"). %% API --export([prop_map_spec/0]). +-export([prop_map_rr_spec/0]). -prop_map_spec() -> - crdt_properties:crdt_satisfies_partial_spec(antidote_crdt_map_rr, fun op/0, fun spec/2). +prop_map_rr_spec() -> + crdt_properties:crdt_satisfies_partial_spec(map_rr, fun op/0, fun spec/2). spec(Operations1, Value) -> @@ -43,7 +43,7 @@ spec(Operations1, Value) -> io:format("Operations = ~p~n", [Operations]), io:format("GroupedByKey = ~p~n", [GroupedByKey]) end, - nestedSpec(Type, Ops, antidote_crdt_map_rr:get({Key,Type}, Value)) + nestedSpec(Type, Ops, map_rr:get({Key,Type}, Value)) ) end, conjunction( @@ -65,11 +65,11 @@ nestedOps(Operations, {_,Type}=Key) -> end, Resets ++ [{Clock, NestedOp} || {Clock, {update, {Key2, NestedOp}}} <- Operations, Key == Key2]. -nestedSpec(antidote_crdt_map_rr, Ops, Value) -> spec(Ops, Value); -% nestedSpec(antidote_crdt_orset, Ops) -> prop_crdt_orset:add_wins_set_spec(Ops); -% nestedSpec(antidote_crdt_big_counter, Ops) -> prop_crdt_big_counter:big_counter_spec(Ops); -nestedSpec(antidote_crdt_set_rw, Ops, Value) -> - (crdt_properties:spec_to_partial(fun prop_crdt_set_rw:rem_wins_set_spec/1))(Ops, Value). +nestedSpec(map_rr, Ops, Value) -> spec(Ops, Value); +% nestedSpec(set_aw, Ops) -> prop_set_aw:spec(Ops); +% nestedSpec(counter_fat, Ops) -> prop_counter_fat:spec(Ops); +nestedSpec(set_rw, Ops, Value) -> + (crdt_properties:spec_to_partial(fun prop_set_rw:spec/1))(Ops, Value). % normalizes operations (update-lists into single update-operations) normalizeOp({Clock, {update, List}}, _) when is_list(List) -> @@ -114,14 +114,14 @@ removeDuplicateKeys([{Key,Op}|Rest], Keys) -> nestedOp(Size) -> oneof( [ - % {{key(), prop_crdt_big_counter}, prop_crdt_big_counter:big_counter_op()}, - % {{key(), antidote_crdt_orset}, prop_crdt_orset:set_op()}, - {{key(), antidote_crdt_set_rw}, prop_crdt_set_rw:set_op()} + % {{key(), counter_fat}, prop_counter_fat:op()}, + % {{key(), set_aw}, prop_set_aw:op()}, + {{key(), set_rw}, prop_set_rw:op()} ] ++ if Size > 1 -> - [{{key(), antidote_crdt_map_rr}, ?LAZY(op(Size div 2))}]; + [{{key(), map_rr}, ?LAZY(op(Size div 2))}]; true -> [] end ). @@ -129,7 +129,7 @@ nestedOp(Size) -> typed_key() -> {key(), crdt_type()}. crdt_type() -> - oneof([antidote_crdt_set_rw, antidote_crdt_map_rr]). + oneof([set_rw, map_rr]). key() -> oneof([key1,key2,key3,key4]). diff --git a/test/prop_crdt_lwwreg.erl b/test/prop_register_lww.erl similarity index 91% rename from test/prop_crdt_lwwreg.erl rename to test/prop_register_lww.erl index 514eb48..e1d9735 100644 --- a/test/prop_crdt_lwwreg.erl +++ b/test/prop_register_lww.erl @@ -18,17 +18,17 @@ %% %% ------------------------------------------------------------------- --module(prop_crdt_lwwreg). +-module(prop_register_lww). -define(PROPER_NO_TRANS, true). -include_lib("proper/include/proper.hrl"). %% API --export([prop_lwwreg_spec/0]). +-export([prop_register_lww_spec/0]). -prop_lwwreg_spec() -> - crdt_properties:crdt_satisfies_spec(antidote_crdt_lwwreg, fun op/0, fun spec/1). +prop_register_lww_spec() -> + crdt_properties:crdt_satisfies_spec(register_lww, fun op/0, fun spec/1). spec(Operations) -> diff --git a/test/prop_crdt_mvreg.erl b/test/prop_register_mv.erl similarity index 84% rename from test/prop_crdt_mvreg.erl rename to test/prop_register_mv.erl index e9699cd..16b6fad 100644 --- a/test/prop_crdt_mvreg.erl +++ b/test/prop_register_mv.erl @@ -18,17 +18,17 @@ %% %% ------------------------------------------------------------------- --module(prop_crdt_mvreg). +-module(prop_register_mv). -define(PROPER_NO_TRANS, true). -include_lib("proper/include/proper.hrl"). %% API --export([prop_mvreg_spec/0]). +-export([prop_register_mv_spec/0]). -prop_mvreg_spec() -> - crdt_properties:crdt_satisfies_spec(antidote_crdt_mvreg, fun op/0, fun spec/1). +prop_register_mv_spec() -> + crdt_properties:crdt_satisfies_spec(register_mv, fun op/0, fun spec/1). spec(Operations) -> @@ -36,7 +36,7 @@ spec(Operations) -> -% generates a random counter operation +% generates a random operation op() -> frequency([ {5, {assign, oneof([a,b,c,d,e,f,g,h,i])}}, diff --git a/test/prop_crdt_orset.erl b/test/prop_set_aw.erl similarity index 86% rename from test/prop_crdt_orset.erl rename to test/prop_set_aw.erl index 2099403..5c0ee7a 100644 --- a/test/prop_crdt_orset.erl +++ b/test/prop_set_aw.erl @@ -18,20 +18,20 @@ %% %% ------------------------------------------------------------------- --module(prop_crdt_orset). +-module(prop_set_aw). -define(PROPER_NO_TRANS, true). -include_lib("proper/include/proper.hrl"). %% API --export([prop_orset_spec/0, set_op/0, add_wins_set_spec/1]). +-export([prop_set_aw_spec/0, op/0, spec/1]). -prop_orset_spec() -> - crdt_properties:crdt_satisfies_spec(antidote_crdt_orset, fun set_op/0, fun add_wins_set_spec/1). +prop_set_aw_spec() -> + crdt_properties:crdt_satisfies_spec(set_aw, fun op/0, fun spec/1). -add_wins_set_spec(Operations1) -> +spec(Operations1) -> Operations = lists:flatmap(fun normalizeOperation/1, Operations1), lists:usort( % all X, @@ -52,8 +52,8 @@ normalizeOperation({Clock, {remove_all, Elems}}) -> normalizeOperation(X) -> [X]. -% generates a random counter operation -set_op() -> +% generates a random operation +op() -> oneof([ {add, set_element()}, {add_all, list(set_element())}, @@ -63,5 +63,4 @@ set_op() -> ]). set_element() -> - oneof([a,b]). - + oneof([a,b]). \ No newline at end of file diff --git a/test/prop_crdt_gset.erl b/test/prop_set_go.erl similarity index 84% rename from test/prop_crdt_gset.erl rename to test/prop_set_go.erl index ac50d69..718a63e 100644 --- a/test/prop_crdt_gset.erl +++ b/test/prop_set_go.erl @@ -18,27 +18,27 @@ %% %% ------------------------------------------------------------------- --module(prop_crdt_gset). +-module(prop_set_go). -define(PROPER_NO_TRANS, true). -include_lib("proper/include/proper.hrl"). %% API --export([prop_gset_spec/0]). +-export([prop_set_go_spec/0]). -prop_gset_spec() -> - crdt_properties:crdt_satisfies_spec(antidote_crdt_gset, fun set_op/0, fun add_wins_set_spec/1). +prop_set_go_spec() -> + crdt_properties:crdt_satisfies_spec(set_go, fun op/0, fun spec/1). -add_wins_set_spec(Operations) -> +spec(Operations) -> lists:usort( [X || {_, {add, X}} <- Operations] ++ [X || {_, {add_all, Xs}} <- Operations, X <- Xs] ). % generates a random counter operation -set_op() -> +op() -> oneof([ {add, set_element()}, {add_all, list(set_element())} diff --git a/test/prop_crdt_set_rw.erl b/test/prop_set_rw.erl similarity index 88% rename from test/prop_crdt_set_rw.erl rename to test/prop_set_rw.erl index eb5680a..cc67da5 100644 --- a/test/prop_crdt_set_rw.erl +++ b/test/prop_set_rw.erl @@ -18,20 +18,20 @@ %% %% ------------------------------------------------------------------- --module(prop_crdt_set_rw). +-module(prop_set_rw). -define(PROPER_NO_TRANS, true). -include_lib("proper/include/proper.hrl"). %% API --export([prop_orset_spec/0, set_op/0, rem_wins_set_spec/1]). +-export([prop_set_rw_spec/0, op/0, spec/1]). -prop_orset_spec() -> - crdt_properties:crdt_satisfies_spec(antidote_crdt_set_rw, fun set_op/0, fun rem_wins_set_spec/1). +prop_set_rw_spec() -> + crdt_properties:crdt_satisfies_spec(set_rw, fun op/0, fun spec/1). -rem_wins_set_spec(Operations1) -> +spec(Operations1) -> Operations2 = crdt_properties:filter_resets(Operations1), Operations = lists:flatmap(fun normalizeOperation/1, Operations2), RemoveClocks = @@ -55,7 +55,7 @@ normalizeOperation(X) -> [X]. % generates a random counter operation -set_op() -> +op() -> oneof([ {add, set_element()}, {add_all, list(set_element())}, From 599e4bcde9c73ba065da4e343840355da7ac6f85 Mon Sep 17 00:00:00 2001 From: Georges Younes Date: Mon, 22 Jan 2018 22:00:58 +0000 Subject: [PATCH 2/6] remove experimental --- TEST-file_antidote_crdt.app.xml | 265 +++++++++++--------------- src/antidote_crdt.erl | 5 +- src/integer.erl | 136 -------------- src/map_aw.erl | 233 ----------------------- src/rga.erl | 316 -------------------------------- test/prop_integer.erl | 61 ------ test/prop_map_aw.erl | 122 ------------ 7 files changed, 103 insertions(+), 1035 deletions(-) delete mode 100644 src/integer.erl delete mode 100644 src/map_aw.erl delete mode 100644 src/rga.erl delete mode 100644 test/prop_integer.erl delete mode 100644 test/prop_map_aw.erl diff --git a/TEST-file_antidote_crdt.app.xml b/TEST-file_antidote_crdt.app.xml index d9bc309..2f33b80 100644 --- a/TEST-file_antidote_crdt.app.xml +++ b/TEST-file_antidote_crdt.app.xml @@ -1,5 +1,5 @@ - + @@ -40,22 +40,22 @@ - + FatCnt0 = [] -Increment1 = {<<62,229,225,101,155,99,133,91,227,61,11,235,224,164,183,38,103, - 164,236,116>>, +Increment1 = {<<79,163,225,87,137,153,10,149,244,244,101,188,94,186,136,66,196, + 23,201,161>>, 5} -FatCnt1 = [{<<62,229,225,101,155,99,133,91,227,61,11,235,224,164,183,38,103, - 164,236,116>>, +FatCnt1 = [{<<79,163,225,87,137,153,10,149,244,244,101,188,94,186,136,66,196, + 23,201,161>>, 5}] -Decrement1 = {<<109,42,58,116,201,67,165,127,35,89,44,40,33,170,78,250,42,8, - 202,146>>, +Decrement1 = {<<235,201,203,141,97,91,245,214,11,134,34,86,222,145,242,44,225, + 56,1,21>>, -2} -FatCnt2 = [{<<62,229,225,101,155,99,133,91,227,61,11,235,224,164,183,38,103, - 164,236,116>>, +FatCnt2 = [{<<79,163,225,87,137,153,10,149,244,244,101,188,94,186,136,66,196, + 23,201,161>>, 5}, - {<<109,42,58,116,201,67,165,127,35,89,44,40,33,170,78,250,42,8,202, - 146>>, + {<<235,201,203,141,97,91,245,214,11,134,34,86,222,145,242,44,225,56, + 1,21>>, -2}] @@ -93,22 +93,17 @@ FatCnt2 = [{<<62,229,225,101,155,99,133,91,227,61,11,235,224,164,183,38,10 - Reset1Effect = {[<<195,210,219,190,70,145,56,165,234,10,186,120,85,149,20,34, - 217,1,76,53>>], + Reset1Effect = {[<<69,2,50,41,144,119,5,212,38,255,168,248,50,161,9,27,6,151, + 170,12>>], []} Enable1Effect = {[], - [<<195,210,219,190,70,145,56,165,234,10,186,120,85,149,20, - 34,217,1,76,53>>]} -Flag1a = [<<195,210,219,190,70,145,56,165,234,10,186,120,85,149,20,34,217,1, - 76,53>>] + [<<69,2,50,41,144,119,5,212,38,255,168,248,50,161,9,27,6, + 151,170,12>>]} +Flag1a = [<<69,2,50,41,144,119,5,212,38,255,168,248,50,161,9,27,6,151,170,12>>] Flag1b = [] - - - - @@ -121,26 +116,26 @@ Flag1b = [] - + Map0 = {dict,0,16,16,8,80,48, {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} Incr1 = {[{{a,counter_fat}, - {ok,{<<90,217,140,224,131,4,221,75,106,101,16,227,80,36,80,12,72,7, - 129,117>>, + {ok,{<<74,85,229,123,119,44,81,145,47,2,158,146,243,17,123,86,57, + 221,184,14>>, 1}}}], []} Map1a = {dict,1,16,16,8,80,48, {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[], [[{a,counter_fat}, - {<<90,217,140,224,131,4,221,75,106,101,16,227,80,36,80,12,72, - 7,129,117>>, + {<<74,85,229,123,119,44,81,145,47,2,158,146,243,17,123,86,57, + 221,184,14>>, 1}]]}}} Reset1 = {[], [{{a,counter_fat}, - {ok,[<<90,217,140,224,131,4,221,75,106,101,16,227,80,36,80,12, - 72,7,129,117>>]}}]} + {ok,[<<74,85,229,123,119,44,81,145,47,2,158,146,243,17,123,86, + 57,221,184,14>>]}}]} Map1b = {dict,0,16,16,8,80,48, {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} @@ -156,16 +151,16 @@ Map1d = {dict,0,16,16,8,80,48, {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} Incr2 = {[{{a,counter_fat}, - {ok,{<<174,93,117,201,201,242,76,191,204,5,14,247,5,12,185,175,182, - 100,250,90>>, + {ok,{<<101,22,237,250,225,241,253,26,122,69,55,5,87,251,196,216,44, + 158,2,50>>, 2}}}], []} Map1e = {dict,1,16,16,8,80,48, {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[], [[{a,counter_fat}, - {<<174,93,117,201,201,242,76,191,204,5,14,247,5,12,185,175, - 182,100,250,90>>, + {<<101,22,237,250,225,241,253,26,122,69,55,5,87,251,196,216, + 44,158,2,50>>, 2}]]}}} @@ -174,15 +169,15 @@ Map1e = {dict,1,16,16,8,80,48, Map0 = [] Add1 = {[{{s,set_rw}, {ok,[{a,[], - [<<144,186,153,131,6,149,158,26,233,139,32,221,203,9,0,167, - 190,251,115,6>>], + [<<15,2,183,52,1,129,25,209,44,236,235,161,123,133,255,149, + 179,71,216,207>>], []}]}}], []} Map1a = [{{s,set_rw},[a]}] Reset1 = {[], [{{s,set_rw}, - {ok,[{a,[<<144,186,153,131,6,149,158,26,233,139,32,221,203,9,0, - 167,190,251,115,6>>], + {ok,[{a,[<<15,2,183,52,1,129,25,209,44,236,235,161,123,133,255, + 149,179,71,216,207>>], [],[]}]}}]} Map1b = [] Remove1 = {[],[{{s,set_rw},{ok,[]}}]} @@ -192,8 +187,8 @@ Reset2 = {[],[]} Map1d = [] Add2 = {[{{s,set_rw}, {ok,[{b,[], - [<<78,143,165,77,13,204,180,77,155,72,128,231,234,175,100, - 249,27,226,211,37>>], + [<<104,83,210,194,247,72,102,176,114,164,216,66,193,185,212, + 222,171,8,159,50>>], []}]}}], []} Map1e = [{{s,set_rw},[b]}] @@ -207,8 +202,8 @@ Map1e = [{{s,set_rw},[b]}] Add1 = {[{{a,map_rr}, {ok,{[{{a,set_rw}, {ok,[{a,[], - [<<144,188,135,255,56,206,22,48,242,17,67,44,94,225, - 106,0,102,160,98,53>>], + [<<109,155,120,190,214,108,38,209,143,129,220,25,171, + 148,92,229,137,170,212,213>>], []}]}}], []}}}], []} @@ -220,8 +215,8 @@ Map1a = {dict,1,16,16,8,80,48, {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, {{[[{a,set_rw}, {a, - {[<<144,188,135,255,56,206,22,48,242,17,67,44,94,225,106,0, - 102,160,98,53>>], + {[<<109,155,120,190,214,108,38,209,143,129,220,25,171,148, + 92,229,137,170,212,213>>], []}}]], [],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}}]], [],[],[],[],[],[]}}} @@ -229,8 +224,8 @@ Reset1 = {[], [{{a,map_rr}, {ok,{[], [{{a,set_rw}, - {ok,[{a,[<<144,188,135,255,56,206,22,48,242,17,67,44,94, - 225,106,0,102,160,98,53>>], + {ok,[{a,[<<109,155,120,190,214,108,38,209,143,129,220,25, + 171,148,92,229,137,170,212,213>>], [],[]}]}}]}}}]} Map1b = {dict,0,16,16,8,80,48, {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, @@ -262,62 +257,6 @@ Map1b = {dict,0,16,16,8,80,48, - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -346,30 +285,30 @@ Map1b = {dict,0,16,16,8,80,48, - + ResetEffect = [] Add1Effect = [{a,[], - [<<9,61,116,97,215,219,20,86,213,51,25,178,50,111,152,180, - 194,50,186,185>>], + [<<191,64,153,229,112,202,201,227,225,101,108,112,166,29,177, + 54,166,242,161,130>>], []}] Add2Effect = [{a,[], - [<<71,28,40,1,175,57,53,5,247,160,193,248,52,124,178,189,60, - 234,133,117>>], + [<<120,235,201,223,6,166,55,118,167,226,32,79,130,184,152,49, + 153,125,190,38>>], []}] Set1a = [] -Set1b = [{a,{[<<9,61,116,97,215,219,20,86,213,51,25,178,50,111,152,180,194,50, - 186,185>>], +Set1b = [{a,{[<<191,64,153,229,112,202,201,227,225,101,108,112,166,29,177,54, + 166,242,161,130>>], []}}] -Set2a = [{a,{[<<71,28,40,1,175,57,53,5,247,160,193,248,52,124,178,189,60,234, - 133,117>>], +Set2a = [{a,{[<<120,235,201,223,6,166,55,118,167,226,32,79,130,184,152,49,153, + 125,190,38>>], []}}] -Set2b = [{a,{[<<71,28,40,1,175,57,53,5,247,160,193,248,52,124,178,189,60,234, - 133,117>>], +Set2b = [{a,{[<<120,235,201,223,6,166,55,118,167,226,32,79,130,184,152,49,153, + 125,190,38>>], []}}] -Set2c = [{a,{[<<71,28,40,1,175,57,53,5,247,160,193,248,52,124,178,189,60,234, - 133,117>>, - <<9,61,116,97,215,219,20,86,213,51,25,178,50,111,152,180,194,50, - 186,185>>], +Set2c = [{a,{[<<120,235,201,223,6,166,55,118,167,226,32,79,130,184,152,49,153, + 125,190,38>>, + <<191,64,153,229,112,202,201,227,225,101,108,112,166,29,177,54, + 166,242,161,130>>], []}}] @@ -380,22 +319,22 @@ Set2c = [{a,{[<<71,28,40,1,175,57,53,5,247,160,193,248,52,124,178,189,60,2 Set0 = [] -Set1 = [{a,{[<<37,12,247,140,101,213,116,236,245,70,75,244,120,124,111,177,94, - 115,136,49>>], +Set1 = [{a,{[<<198,27,62,81,207,95,219,90,16,126,234,14,41,223,108,156,130, + 212,163,169>>], []}}] -Set2 = [{a,{[<<37,12,247,140,101,213,116,236,245,70,75,244,120,124,111,177,94, - 115,136,49>>], +Set2 = [{a,{[<<198,27,62,81,207,95,219,90,16,126,234,14,41,223,108,156,130, + 212,163,169>>], []}}, - {b,{[<<131,76,3,181,249,16,141,78,102,33,17,146,57,89,204,124,242,251, - 152,110>>], + {b,{[<<230,21,85,205,190,115,28,114,16,35,115,253,143,104,186,58,111, + 197,128,245>>], []}}] Add1Effect = [{a,[], - [<<37,12,247,140,101,213,116,236,245,70,75,244,120,124,111, - 177,94,115,136,49>>], + [<<198,27,62,81,207,95,219,90,16,126,234,14,41,223,108,156, + 130,212,163,169>>], []}] Add2Effect = [{b,[], - [<<131,76,3,181,249,16,141,78,102,33,17,146,57,89,204,124, - 242,251,152,110>>], + [<<230,21,85,205,190,115,28,114,16,35,115,253,143,104,186,58, + 111,197,128,245>>], []}] @@ -403,54 +342,54 @@ Add2Effect = [{b,[], ResetEffect = [] Add3Effect = [{b,[], - [<<126,192,154,139,181,139,79,137,228,17,57,195,98,27,220, - 129,183,194,162,71>>], + [<<16,255,41,104,203,117,206,26,91,147,191,149,153,124,83,38, + 186,23,20,108>>], []}] Set1a = [] -Set3a = [{b,{[<<126,192,154,139,181,139,79,137,228,17,57,195,98,27,220,129, - 183,194,162,71>>], +Set3a = [{b,{[<<16,255,41,104,203,117,206,26,91,147,191,149,153,124,83,38,186, + 23,20,108>>], []}}] -Set1b = [{b,{[<<126,192,154,139,181,139,79,137,228,17,57,195,98,27,220,129, - 183,194,162,71>>], +Set1b = [{b,{[<<16,255,41,104,203,117,206,26,91,147,191,149,153,124,83,38,186, + 23,20,108>>], []}}] Remove1Effect = [{b,[],[], - [<<237,78,51,60,180,91,33,189,155,79,254,87,26,186,31, - 197,173,44,142,128>>]}] + [<<118,7,168,5,190,218,129,243,36,149,33,76,127,116,157, + 243,230,6,70,79>>]}] Add3Effect = [{a,[], - [<<171,11,140,120,32,164,139,106,199,202,155,28,89,150,30, - 165,212,251,197,140>>], + [<<206,165,193,96,223,95,187,111,238,153,137,27,219,76,155, + 153,47,251,101,159>>], []}] Set1a = [{b,{[], - [<<237,78,51,60,180,91,33,189,155,79,254,87,26,186,31,197,173, - 44,142,128>>]}}] -Set3a = [{a,{[<<171,11,140,120,32,164,139,106,199,202,155,28,89,150,30,165, - 212,251,197,140>>], + [<<118,7,168,5,190,218,129,243,36,149,33,76,127,116,157,243, + 230,6,70,79>>]}}] +Set3a = [{a,{[<<206,165,193,96,223,95,187,111,238,153,137,27,219,76,155,153, + 47,251,101,159>>], []}}] -Set1b = [{a,{[<<171,11,140,120,32,164,139,106,199,202,155,28,89,150,30,165, - 212,251,197,140>>], +Set1b = [{a,{[<<206,165,193,96,223,95,187,111,238,153,137,27,219,76,155,153, + 47,251,101,159>>], []}}, {b,{[], - [<<237,78,51,60,180,91,33,189,155,79,254,87,26,186,31,197,173, - 44,142,128>>]}}] + [<<118,7,168,5,190,218,129,243,36,149,33,76,127,116,157,243, + 230,6,70,79>>]}}] Reset3Effect = [] Add2Effect = [{a,[], - [<<2,163,95,200,95,230,178,240,63,46,227,141,200,45,69,127, - 69,42,149,163>>], + [<<141,180,119,153,0,28,215,133,20,176,36,77,78,141,11,7,202, + 149,139,184>>], []}] -Set2a = [{a,{[<<2,163,95,200,95,230,178,240,63,46,227,141,200,45,69,127,69,42, - 149,163>>], +Set2a = [{a,{[<<141,180,119,153,0,28,215,133,20,176,36,77,78,141,11,7,202,149, + 139,184>>], []}}] Set3a = [] -Set3b = [{a,{[<<2,163,95,200,95,230,178,240,63,46,227,141,200,45,69,127,69,42, - 149,163>>], +Set3b = [{a,{[<<141,180,119,153,0,28,215,133,20,176,36,77,78,141,11,7,202,149, + 139,184>>], []}}] @@ -458,29 +397,29 @@ Set3b = [{a,{[<<2,163,95,200,95,230,178,240,63,46,227,141,200,45,69,127,69 Reset3Effect = [] Add2Effect = [{a,[], - [<<95,199,58,253,22,138,220,2,162,254,99,234,151,250,191,58, - 44,131,56,116>>], + [<<174,157,127,154,150,87,175,116,131,78,198,164,87,18,86, + 186,88,110,226,112>>], []}] -Set2a = [{a,{[<<95,199,58,253,22,138,220,2,162,254,99,234,151,250,191,58,44, - 131,56,116>>], +Set2a = [{a,{[<<174,157,127,154,150,87,175,116,131,78,198,164,87,18,86,186,88, + 110,226,112>>], []}}] Set3a = [] -Set3b = [{a,{[<<95,199,58,253,22,138,220,2,162,254,99,234,151,250,191,58,44, - 131,56,116>>], +Set3b = [{a,{[<<174,157,127,154,150,87,175,116,131,78,198,164,87,18,86,186,88, + 110,226,112>>], []}}] - - Reset2Effect = [{a,[<<111,20,9,38,112,164,37,29,179,54,244,118,35,168,32,8,78, - 10,26,12>>], + + Reset2Effect = [{a,[<<208,100,243,7,159,179,18,124,253,35,49,77,225,110,192, + 193,129,14,142,184>>], [],[]}] Add2Effect = [{a,[], - [<<111,20,9,38,112,164,37,29,179,54,244,118,35,168,32,8,78, - 10,26,12>>], + [<<208,100,243,7,159,179,18,124,253,35,49,77,225,110,192,193, + 129,14,142,184>>], []}] -Set2a = [{a,{[<<111,20,9,38,112,164,37,29,179,54,244,118,35,168,32,8,78,10,26, - 12>>], +Set2a = [{a,{[<<208,100,243,7,159,179,18,124,253,35,49,77,225,110,192,193,129, + 14,142,184>>], []}}] Set2b = [] diff --git a/src/antidote_crdt.erl b/src/antidote_crdt.erl index 8523640..5bf5c63 100644 --- a/src/antidote_crdt.erl +++ b/src/antidote_crdt.erl @@ -47,7 +47,6 @@ -define(CRDTS, [counter_pn, counter_b, counter_fat, - integer, flag_ew, flag_dw, set_go, @@ -56,9 +55,7 @@ register_lww, register_mv, map_go, - map_aw, - map_rr, - rga]). + map_rr]). -export([is_type/1 ]). diff --git a/src/integer.erl b/src/integer.erl deleted file mode 100644 index 9e1fd27..0000000 --- a/src/integer.erl +++ /dev/null @@ -1,136 +0,0 @@ -%% ------------------------------------------------------------------- -%% -%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. -%% -%% This file is provided to you under the Apache License, -%% Version 2.0 (the "License"); you may not use this file -%% except in compliance with the License. You may obtain -%% a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, -%% software distributed under the License is distributed on an -%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -%% KIND, either express or implied. See the License for the -%% specific language governing permissions and limitations -%% under the License. -%% -%% ------------------------------------------------------------------- - -%% integer: A convergent, replicated, operation based integer -%% -%% This is an extension of the counter: -%% Besides the increment operation, it also provides a set operation -%% -%% Semantics: -%% The value of the counter is determines as follows: -%% 1) as base-values take the value of the latest (concurrent) set-operations (or 0 if there are none) -%% 2) for each base-value: add the increments which are concurrent to or after the respective set and add them to the base value -%% 3) take the maximum of these values (note that this is not always the maximum base-value) -%% -%% Implementation: -%% A mix of counter and mvreg - --module(integer). - --behaviour(antidote_crdt). - --ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). --endif. - --export([ new/0, - value/1, - downstream/2, - update/2, - equal/2, - to_binary/1, - from_binary/1, - is_operation/1, - require_state_downstream/1 - ]). - --type state() :: {[{term(), integer()}], integer()}. --type update() :: - {increment, integer()} - | {set, integer()} - | {reset, {}}. --type effect() :: - {increment, integer()} - | {set, term(), [term()], integer()}. --type value() :: integer(). - - --spec new() -> state(). -new() -> - {[{initial, 0}], 0}. - --spec value(state()) -> value(). -value({Vals, Delta}) -> - lists:max([X || {_, X} <- Vals]) + Delta. - --spec downstream(update(), state()) -> {ok, effect()}. -downstream({increment, N}, _State) -> - {ok, {increment, N}}; -downstream({set, N}, {Vals, Delta}) -> - Overridden = [Tag || {Tag, _} <- Vals], - {ok, {set, unique(), Overridden, N-Delta}}; -downstream({reset, {}}, State) -> - % resetting means setting value to 0 - downstream({set, 0}, State). - -unique() -> - crypto:strong_rand_bytes(20). - -%% @doc Update a `pncounter()'. The first argument is either the atom -%% `increment' or `decrement' or the two tuples `{increment, pos_integer()}' or -%% `{decrement, pos_integer()}'. -%% In the case of the former, the operation's amount -%% is `1'. Otherwise it is the value provided in the tuple's second element. -%% The 2nd argument is the `pncounter()' to update. -%% -%% returns the updated `pncounter()' --spec update(effect(), state()) -> {ok, state()}. -update({set, Token, Overridden, N}, {Vals, Delta}) -> - Surviving = [{T, V} || {T, V} <- Vals, not lists:member(T, Overridden)], - {ok, {[{Token, N}|Surviving], Delta}}; -update({increment, N}, {Vals, Delta}) -> - {ok, {Vals, Delta + N}}. - -%% @doc Compare if two `pncounter()' are equal. Only returns `true()' if both -%% of their positive and negative entries are equal. --spec equal(state(), state()) -> boolean(). -equal(PNCnt1, PNCnt2) -> - PNCnt1 =:= PNCnt2. - --spec to_binary(state()) -> binary(). -to_binary(PNCounter) -> - term_to_binary(PNCounter). - -from_binary(Bin) -> - %% @TODO something smarter - {ok, binary_to_term(Bin)}. - -%% @doc The following operation verifies -%% that Operation is supported by this particular CRDT. --spec is_operation(term()) -> boolean(). -is_operation({increment, N}) when is_integer(N) -> true; -is_operation({set, N}) when is_integer(N) -> true; -is_operation({reset, {}}) -> true; -is_operation(_) -> false. - -%% @doc Returns true if ?MODULE:downstream/2 needs the state of crdt -%% to generate downstream effect -require_state_downstream({set, _}) -> true; -require_state_downstream({reset, {}}) -> true; -require_state_downstream(_) -> false. - - - -%% =================================================================== -%% EUnit tests -%% =================================================================== --ifdef(TEST). - --endif. diff --git a/src/map_aw.erl b/src/map_aw.erl deleted file mode 100644 index 10fb5e2..0000000 --- a/src/map_aw.erl +++ /dev/null @@ -1,233 +0,0 @@ -%% ------------------------------------------------------------------- -%% -%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. -%% -%% This file is provided to you under the Apache License, -%% Version 2.0 (the "License"); you may not use this file -%% except in compliance with the License. You may obtain -%% a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, -%% software distributed under the License is distributed on an -%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -%% KIND, either express or implied. See the License for the -%% specific language governing permissions and limitations -%% under the License. -%% -%% ------------------------------------------------------------------- - -%% @doc module antidote_crdt_map - A add-wins map -%% -%% This map forwards all operations to the embedded CRDTs. -%% Deleting a key tries to reset the entry to its initial state -%% -%% An element exists in a map, if there is at least one update on the key, which is not followed by a remove -%% -%% Resetting the map means removing all the current entries -%% -%% Implementation note: -%% The implementation of Add-wins semantic is the same as in orset: -%% Each element has a set of add-tokens. -%% An entry is in the map, if the set of add-tokens is not empty. -%% When an entry is removed, the value is still kept in the state, so that -%% concurrent updates can be reconciled. -%% This could be optimized for certain types - --module(map_aw). - --behaviour(antidote_crdt). - -%% API --export([new/0, value/1, update/2, equal/2, - to_binary/1, from_binary/1, is_operation/1, downstream/2, require_state_downstream/1]). - --ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). --endif. - - --type typedKey() :: {Key::term(), Type::atom()}. --type token() :: term(). --type state() :: dict:dict(typedKey(), {[token()], NestedState::term()}). --type op() :: - {update, nested_op()} - | {update, [nested_op()]} - | {remove, typedKey()} - | {remove, [typedKey()]} - | {batch, {Updates::[nested_op()], Removes::[typedKey()]}} - | {reset, {}}. --type nested_op() :: {typedKey(), Op::term()}. --type effect() :: - {Adds::[nested_downstream()], Removed::[nested_downstream()], AddedToken::token()}. --type nested_downstream() :: {typedKey(), none | {ok, Effect::term()}, RemovedTokens::[token()]}. - --spec new() -> state(). -new() -> - dict:new(). - --spec value(state()) -> [{typedKey(), Value::term()}]. -value(Map) -> - lists:sort([{{Key, Type}, Type:value(Value)} || {{Key, Type}, {Tokens, Value}} <- dict:to_list(Map), Tokens =/= []]). - --spec require_state_downstream(op()) -> boolean(). -require_state_downstream(_Op) -> - true. - --spec downstream(op(), state()) -> {ok, effect()}. -downstream({update, {{Key, Type}, Op}}, CurrentMap) -> - downstream({update, [{{Key, Type}, Op}]}, CurrentMap); -downstream({update, NestedOps}, CurrentMap) -> - downstream({batch, {NestedOps, []}}, CurrentMap); -downstream({remove, {Key, Type}}, CurrentMap) -> - downstream({remove, [{Key, Type}]}, CurrentMap); -downstream({remove, Keys}, CurrentMap) -> - downstream({batch, {[], Keys}}, CurrentMap); -downstream({batch, {Updates, Removes}}, CurrentMap) -> - UpdateEffects = [generate_downstream_update(Op, CurrentMap) || Op <- Updates], - RemoveEffects = [generate_downstream_remove(Key, CurrentMap) || Key <- Removes], - Token = - case UpdateEffects of - [] -> <<>>; % no token required - _ -> unique() - end, - {ok, {UpdateEffects, RemoveEffects, Token}}; -downstream({reset, {}}, CurrentMap) -> - % reset removes all keys - AllKeys = [Key || {Key, _Val} <- value(CurrentMap)], - downstream({remove, AllKeys}, CurrentMap). - - --spec generate_downstream_update({typedKey(), Op::term()}, state()) -> nested_downstream(). -generate_downstream_update({{Key, Type}, Op}, CurrentMap) -> - {CurrentTokens, CurrentState} = - case dict:is_key({Key, Type}, CurrentMap) of - true -> dict:fetch({Key, Type}, CurrentMap); - false -> {[], Type:new()} - end, - {ok, DownstreamEffect} = Type:downstream(Op, CurrentState), - {{Key, Type}, {ok, DownstreamEffect}, CurrentTokens}. - - --spec generate_downstream_remove(typedKey(), state()) -> nested_downstream(). -generate_downstream_remove({Key, Type}, CurrentMap) -> - {CurrentTokens, CurrentState} = - case dict:is_key({Key, Type}, CurrentMap) of - true -> dict:fetch({Key, Type}, CurrentMap); - false -> {[], Type:new()} - end, - DownstreamEffect = - case Type:is_operation({reset, {}}) of - true -> - {ok, _} = Type:downstream({reset, {}}, CurrentState); - false -> - none - end, - {{Key, Type}, DownstreamEffect, CurrentTokens}. - - -unique() -> - crypto:strong_rand_bytes(20). - --spec update(effect(), state()) -> {ok, state()}. -update({Updates, Removes, AddedToken}, State) -> - State2 = lists:foldl(fun(E, S) -> update(E, [AddedToken], S) end, State, Updates), - State3 = lists:foldl(fun(E, S) -> update(E, [], S) end, State2, Removes), - {ok, State3}. - -update({{Key, Type}, {ok, Op}, RemovedTokens}, NewTokens, Map) -> - case dict:find({Key, Type}, Map) of - {ok, {Tokens, State}} -> - UpdatedTokens = NewTokens ++ (Tokens -- RemovedTokens), - {ok, UpdatedState} = Type:update(Op, State), - dict:store({Key, Type}, {UpdatedTokens, UpdatedState}, Map); - error -> - NewValue = Type:new(), - {ok, NewValueUpdated} = Type:update(Op, NewValue), - dict:store({Key, Type}, {NewTokens, NewValueUpdated}, Map) - end; -update({{Key, Type}, none, RemovedTokens}, NewTokens, Map) -> - case dict:find({Key, Type}, Map) of - {ok, {Tokens, State}} -> - UpdatedTokens = NewTokens ++ (Tokens -- RemovedTokens), - dict:store({Key, Type}, {UpdatedTokens, State}, Map); - error -> - NewValue = Type:new(), - dict:store({Key, Type}, {NewTokens, NewValue}, Map) - end. - - - -equal(Map1, Map2) -> - Map1 == Map2. % TODO better implementation (recursive equals) - - --define(TAG, 101). --define(V1_VERS, 1). - -to_binary(Policy) -> - <>. - -from_binary(<>) -> - {ok, binary_to_term(Bin)}. - -is_operation(Operation) -> - case Operation of - {update, {{_Key, Type}, Op}} -> - antidote_crdt:is_type(Type) - andalso Type:is_operation(Op); - {update, Ops} when is_list(Ops) -> - distinct([Key || {Key, _} <- Ops]) - andalso lists:all(fun(Op) -> is_operation({update, Op}) end, Ops); - {remove, {_Key, Type}} -> - antidote_crdt:is_type(Type); - {remove, Keys} when is_list(Keys) -> - distinct(Keys) - andalso lists:all(fun(Key) -> is_operation({remove, Key}) end, Keys); - {batch, {Updates, Removes}} -> - is_list(Updates) - andalso is_list(Removes) - andalso distinct(Removes ++ [Key || {Key, _} <- Updates]) - andalso lists:all(fun(Key) -> is_operation({remove, Key}) end, Removes) - andalso lists:all(fun(Op) -> is_operation({update, Op}) end, Updates); - {reset, {}} -> true; - _ -> - false - end. - -distinct([]) -> true; -distinct([X|Xs]) -> - not lists:member(X, Xs) andalso distinct(Xs). - -%% =================================================================== -%% EUnit tests -%% =================================================================== - --ifdef(TEST). - -reset1_test() -> - Set0 = new(), - % DC1: a.incr - {ok, Incr1} = downstream({update, {{a, integer}, {increment, 1}}}, Set0), - {ok, Set1a} = update(Incr1, Set0), - % DC1 reset - {ok, Reset1} = downstream({reset, {}}, Set1a), - {ok, Set1b} = update(Reset1, Set1a), - % DC2 a.remove - {ok, Remove1} = downstream({remove, {a, integer}}, Set0), - {ok, Set2a} = update(Remove1, Set0), - % DC2 --> DC1 - {ok, Set1c} = update(Remove1, Set1b), - % DC1 reset - {ok, Reset2} = downstream({reset, {}}, Set1c), - {ok, Set1d} = update(Reset2, Set1c), - % DC1: a.incr - {ok, Incr2} = downstream({update, {{a, integer}, {increment, 0}}}, Set1d), - {ok, Set1e} = update(Incr2, Set1d), - - ?assertEqual([], value(Set2a)), - ?assertEqual([], value(Set1d)), - ?assertEqual([{{a, integer}, 1}], value(Set1e)). - --endif. \ No newline at end of file diff --git a/src/rga.erl b/src/rga.erl deleted file mode 100644 index e89efb4..0000000 --- a/src/rga.erl +++ /dev/null @@ -1,316 +0,0 @@ -%% ------------------------------------------------------------------- -%% -%% Copyright (c) 2015 SyncFree Consortium. All Rights Reserved. -%% -%% This file is provided to you under the Apache License, -%% Version 2.0 (the "License"); you may not use this file -%% except in compliance with the License. You may obtain -%% a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, -%% software distributed under the License is distributed on an -%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -%% KIND, either express or implied. See the License for the -%% specific language governing permissions and limitations -%% under the License. -%% -%% ------------------------------------------------------------------- - -%% @doc -%% -%% An operation-based Replicated Growable Array CRDT. -%% -%% As the data structure is operation-based, to issue an operation, one should -%% first call `generate_downstream/3', to get the downstream version of the -%% operation, and then call `update/2'. -%% -%% It provides two operations: addRight, which adds an element to the RGA, and remove, -%% which removes an element from the RGA. -%% -%% This implementation is based on the paper cited below. -%% -%% @reference Marc Shapiro, Nuno Preguiça, Carlos Baquero, Marek Zawirski (2011) A comprehensive study of -%% Convergent and Commutative Replicated Data Types. http://hal.upmc.fr/inria-00555588/ -%% -%% @end --module(rga). - --behaviour(antidote_crdt). - -%% Call backs --export([ new/0, - value/1, - downstream/2, - update/2, - equal/2, - to_binary/1, - from_binary/1, - is_operation/1, - require_state_downstream/1 - ]). - --export([purge_tombstones/1]). - --export_type([rga/0, rga_op/0, rga_downstream_op/0]). - --ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). --endif. - --type vertex() :: {ok | deleted, any(), number()}. - --type rga_downstream_op() :: {addRight, vertex(), vertex()} | {remove, {ok, any(), number()}}. - --type rga_op() :: {addRight, {any(), non_neg_integer()}} | {remove, non_neg_integer()}. - --type rga_result() :: {ok, rga()}. - --type rga() :: [vertex()]. - --spec new() -> []. -new() -> - []. - -%% @doc generate downstream operations. -%% If the operation is addRight, generates a unique token for the new element. -%% If the operation is remove, fetches the vertex of the element to be removed. --spec downstream(rga_op(), rga()) -> {ok, rga_downstream_op()} | {error, {invalid_position, number()}}. -downstream({addRight, {Elem, Position}}, Rga) -> - case (Position < 0) or (Position > length(Rga)) of - true -> {error, {invalid_position, Position}}; - false -> case (Rga == []) or (Position == 0) of - true -> {ok, {addRight, {ok, 0, 0}, {ok, Elem, unique()}}}; - false -> {ok, {addRight, lists:nth(Position, Rga), {ok, Elem, unique()}}} - end - end; -downstream({remove, Position}, Rga) -> - {ok, {remove, lists:nth(Position, Rga)}}. - -%% @doc given an RGA, returns the same RGA, as it represents its own value. --spec value(rga()) -> rga(). -value(Rga) -> - Rga. - -%% @doc This method takes in an rga operation and an rga to perform the operation. -%% It returns either the added Vertex and the new rga in case of an addRight, and the new rga in the case of a remove. --spec update(rga_downstream_op(), rga()) -> rga_result(). -update({addRight, RightVertex, NewVertex}, Rga) -> - recursive_insert(RightVertex, NewVertex, Rga, []); -update({remove, Vertex}, Rga) -> - remove_vertex(Vertex, Rga). - -%% Private -%% @doc recursively looks for the Vertex where the new element should be put to the right of. --spec recursive_insert(vertex(), vertex(), rga(), list()) -> rga_result(). -recursive_insert(_, NewVertex, [], []) -> - {ok, [NewVertex]}; -recursive_insert({ok, 0, 0}, NewVertex, L, []) -> - add_element(NewVertex, L, []); -recursive_insert(RightVertex, NewVertex, [RightVertex | T], L) -> - add_element(NewVertex, T, [RightVertex | L]); -recursive_insert(RightVertex, NewVertex, [H | T], L) -> - recursive_insert(RightVertex, NewVertex, T, [H | L]). - -%% Private -%% @doc the place for the insertion has been found, so now the UIDs are compared to see where to insert. --spec add_element(vertex(), rga(), list()) -> rga_result(). -add_element({Status, Value, UID}, [{Status1, Value1, UID1} | T], L) -> - case UID >= UID1 of - true -> - {ok, lists:reverse(L) ++ [{Status, Value, UID}] ++ [{Status1, Value1, UID1} | T]}; - _ -> - add_element({Status, Value, UID}, T, [{Status1, Value1, UID1} | L]) - end; -add_element(Insert, [], L) -> - {ok, lists:reverse([Insert | L])}. - -%% Private -%% @doc looks for the Vertex to be removed. Once it's found, it's marked as "deleted". -%% The Vertex is not removed from the list, to allow adding elements to its right. --spec remove_vertex(vertex(), rga()) -> rga_result(). -remove_vertex({ok, Value, UID}, Rga) -> - {ok, lists:keyreplace(UID, 3, Rga, {deleted, Value, UID})}. - -%% @doc given an rga, this mehtod looks for all tombstones and removes them, returning the tombstone free rga. --spec purge_tombstones(rga()) -> rga_result(). -purge_tombstones(Rga) -> - L = lists:filter(fun({Status, _, _}) -> Status == ok end, Rga), - {ok, L}. - -%% @doc generates a unique identifier based on the node and a unique reference. -unique() -> - {node(), make_ref()}. - -%% @doc The following operation verifies that Operation is supported by this particular CRDT. --spec is_operation(term()) -> boolean(). -is_operation({addRight, {_, Position}}) -> - (is_integer(Position) and (Position >= 0)); -is_operation({remove, Position})-> - (is_integer(Position) and (Position >= 0)); -is_operation(_) -> - false. - -require_state_downstream(_) -> - true. - -equal(Rga1, Rga2) -> - Rga1 == Rga2. - -to_binary(Rga1) -> - erlang:term_to_binary(Rga1). - -from_binary(Bin) -> - {ok, erlang:binary_to_term(Bin)}. - --ifdef(TEST). - -new_test() -> - ?assertEqual([], new()). - -generate_downstream_invalid_position_test() -> - L = new(), - Result1 = downstream({addRight, {1, 1}}, L), - ?assertMatch({error, {invalid_position, 1}}, Result1), - Result2 = downstream({addRight, {1, -1}}, L), - ?assertMatch({error, {invalid_position, -1}}, Result2). - -generate_downstream_empty_rga_test() -> - L = new(), - {ok, DownstreamOp} = downstream({addRight, {4, 0}}, L), - ?assertMatch({addRight, {ok, 0, 0}, {ok, 4, _}}, DownstreamOp). - -generate_downstream_non_empty_rga_test() -> - L = new(), - {ok, DownstreamOp} = downstream({addRight, {4, 0}}, L), - {ok, L1} = update(DownstreamOp, L), - {ok, DownstreamOp1} = downstream({addRight, {3, 1}}, L1), - ?assertMatch({addRight, {ok, 4, _}, {ok, 3, _}}, DownstreamOp1). - -add_right_in_empty_rga_test() -> - L = new(), - {ok, DownstreamOp} = downstream({addRight, {1, 0}}, L), - {ok, L1} = update(DownstreamOp, L), - ?assertMatch([{ok, 1, _}], L1). - -add_right_in_non_empty_rga_test() -> - L = new(), - {ok, DownstreamOp} = downstream({addRight, {1, 0}}, L), - {ok, L1} = update(DownstreamOp, L), - {ok, DownstreamOp1} = downstream({addRight, {2, 1}}, L1), - {ok, L2} = update(DownstreamOp1, L1), - ?assertMatch([{ok, 1, _}, {ok, 2, _}], L2). - -%% In the tests that follow, the values of generate_downstream are placed by hand ,so -%% the intended scenarios can be correctly tested, not depending on the unique() function. - -insert_in_the_middle_test() -> - L = new(), - DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, - DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, - DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, - {ok, L1} = update(DownstreamOp1, L), - {ok, L2} = update(DownstreamOp2, L1), - {ok, L3} = update(DownstreamOp3, L2), - ?assertMatch([{ok, 1, _}, {ok, 2, _}, {ok, 3, _}], L3). - -remove_first_element_test() -> - L = new(), - DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, - DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, - DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, - {ok, L1} = update(DownstreamOp1, L), - {ok, L2} = update(DownstreamOp2, L1), - {ok, L3} = update(DownstreamOp3, L2), - {ok, DownstreamOp4} = downstream({remove, 1}, L3), - {ok, L4} = update(DownstreamOp4, L3), - ?assertMatch([{deleted, 1, _}, {ok, 2, _}, {ok, 3, _}], L4). - -remove_middle_element_test() -> - L = new(), - DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, - DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, - DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, - {ok, L1} = update(DownstreamOp1, L), - {ok, L2} = update(DownstreamOp2, L1), - {ok, L3} = update(DownstreamOp3, L2), - {ok, DownstreamOp4} = downstream({remove, 2}, L3), - {ok, L4} = update(DownstreamOp4, L3), - ?assertMatch([{ok, 1, _}, {deleted, 2, _}, {ok, 3, _}], L4). - -remove_last_element_test() -> - L = new(), - DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, - DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, - DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, - {ok, L1} = update(DownstreamOp1, L), - {ok, L2} = update(DownstreamOp2, L1), - {ok, L3} = update(DownstreamOp3, L2), - {ok, DownstreamOp4} = downstream({remove, 3}, L3), - {ok, L4} = update(DownstreamOp4, L3), - ?assertMatch([{ok, 1, _}, {ok, 2, _}, {deleted, 3, _}], L4). - -insert_right_of_a_remove_test() -> - L = new(), - DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, - DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, - DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 4}}, - {ok, L1} = update(DownstreamOp1, L), - {ok, L2} = update(DownstreamOp2, L1), - {ok, L3} = update(DownstreamOp3, L2), - {ok, DownstreamOp4} = downstream({remove, 2}, L3), - {ok, L4} = update(DownstreamOp4, L3), - DownstreamOp5 = {addRight, {deleted, 2, 4}, {ok, 4, 3}}, - {ok, L5} = update(DownstreamOp5, L4), - ?assertMatch([{ok, 1, _}, {deleted, 2, _}, {ok, 4, _}, {ok, 3, _}], L5). - -purge_tombstones_test() -> - L = new(), - DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, - DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, - DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, - {ok, L1} = update(DownstreamOp1, L), - {ok, L2} = update(DownstreamOp2, L1), - {ok, L3} = update(DownstreamOp3, L2), - {ok, DownstreamOp4} = downstream({remove, 2}, L3), - {ok, L4} = update(DownstreamOp4, L3), - {ok, L5} = purge_tombstones(L4), - ?assertMatch([{ok, 1, _}, {ok, 3, _}], L5). - -%% This test creates two RGAs and performs updates, checking they reach -%% the same final state after the four updates are aplied in both replicas. -concurrent_updates_in_two_replicas_test() -> - R1_0 = new(), - R2_0 = new(), - {ok, DownstreamOp1} = downstream({addRight, {1, 0}}, R1_0), - {ok, DownstreamOp2} = downstream({addRight, {2, 0}}, R2_0), - {ok, R1_1} = update(DownstreamOp1, R1_0), - {ok, R2_1} = update(DownstreamOp2, R2_0), - {ok, R1_2} = update(DownstreamOp2, R1_1), - {ok, R2_2} = update(DownstreamOp1, R2_1), - ?assertEqual(R1_2, R2_2), - {ok, DownstreamOp3} = downstream({addRight, {3, 2}}, R1_2), - {ok, DownstreamOp4} = downstream({addRight, {4, 2}}, R2_2), - {ok, R1_3} = update(DownstreamOp3, R1_2), - {ok, R2_3} = update(DownstreamOp4, R2_2), - {ok, R1_4} = update(DownstreamOp4, R1_3), - {ok, R2_4} = update(DownstreamOp3, R2_3), - ?assertEqual(R1_4, R2_4). - -is_operation_test() -> - %% addRight checks - ?assertEqual(false, is_operation({addRight, {value, -1}})), - ?assertEqual(true, is_operation({addRight, {value, 0}})), - ?assertEqual(true, is_operation({addRight, {value, 1}})), - - %% remove checks - ?assertEqual(false, is_operation({remove, -1})), - ?assertEqual(true, is_operation({remove, 0})), - ?assertEqual(true, is_operation({remove, 1})), - - %% invalid operation checks - ?assertEqual(false, is_operation({anything, 1})), - ?assertEqual(false, is_operation({add, 1, 4})). - --endif. diff --git a/test/prop_integer.erl b/test/prop_integer.erl deleted file mode 100644 index dd43c15..0000000 --- a/test/prop_integer.erl +++ /dev/null @@ -1,61 +0,0 @@ -%% ------------------------------------------------------------------- -%% -%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. -%% -%% This file is provided to you under the Apache License, -%% Version 2.0 (the "License"); you may not use this file -%% except in compliance with the License. You may obtain -%% a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, -%% software distributed under the License is distributed on an -%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -%% KIND, either express or implied. See the License for the -%% specific language governing permissions and limitations -%% under the License. -%% -%% ------------------------------------------------------------------- - --module(prop_integer). - --define(PROPER_NO_TRANS, true). --include_lib("proper/include/proper.hrl"). - -%% API --export([prop_integer_spec/0, op/0, spec/1]). - - -prop_integer_spec() -> - crdt_properties:crdt_satisfies_spec(integer, fun op/0, fun spec/1). - - -spec(Operations1) -> - Operations = [normalizeOp(Op) || Op <- Operations1], - ConcurrentValues = - [{Clock, Val} || {Clock, {set, Val}} <- Operations, - [] == [Clock2 || {Clock2, {set, _}} <- Operations, Clock =/= Clock2, crdt_properties:clock_le(Clock, Clock2)]], - ConcurrentValues2 = - case ConcurrentValues of - [] -> [{#{}, 0}]; - _ -> ConcurrentValues - end, - Delta = - fun(Clock) -> - lists:sum([X || {C, {increment, X}} <- Operations, not crdt_properties:clock_le(C, Clock)]) - end, - WithDelta = [Val + Delta(Clock) || {Clock,Val} <- ConcurrentValues2], - lists:max(WithDelta). - -normalizeOp({Clock, {reset, {}}}) -> {Clock, {set, 0}}; -normalizeOp(Op) -> Op. - -% generates a random counter operation -op() -> - oneof([ - {set, integer()}, - {increment, integer()}, - {reset, {}} - ]). - diff --git a/test/prop_map_aw.erl b/test/prop_map_aw.erl deleted file mode 100644 index 08bf6c6..0000000 --- a/test/prop_map_aw.erl +++ /dev/null @@ -1,122 +0,0 @@ -%% ------------------------------------------------------------------- -%% -%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. -%% -%% This file is provided to you under the Apache License, -%% Version 2.0 (the "License"); you may not use this file -%% except in compliance with the License. You may obtain -%% a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, -%% software distributed under the License is distributed on an -%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -%% KIND, either express or implied. See the License for the -%% specific language governing permissions and limitations -%% under the License. -%% -%% ------------------------------------------------------------------- - --module(prop_map_aw). - --define(PROPER_NO_TRANS, true). --include_lib("proper/include/proper.hrl"). - -%% API --export([prop_map_aw_spec/0]). - - -prop_map_aw_spec() -> - crdt_properties:crdt_satisfies_spec(map_aw, fun op/0, fun spec/1). - - -spec(Operations1) -> - Operations = lists:flatmap(fun(Op) -> normalizeOp(Op, Operations1) end, Operations1), - % the keys in the map are the ones that were updated and not deleted yet - Keys = lists:usort([Key || - % has an update - {AddClock, {update, {Key, _}}} <- Operations, - % no remove after the update: - [] == [Y || {RemoveClock, {remove, Y}} <- Operations, Key == Y, crdt_properties:clock_le(AddClock, RemoveClock)] - ]), - GroupedByKey = [{Key, nestedOps(Operations, Key)} || Key <- Keys], - NestedSpec = [{{Key,Type}, nestedSpec(Type, Ops)} || {{Key,Type}, Ops} <- GroupedByKey], - %% TODO add reset operations - lists:sort(NestedSpec). - -nestedOps(Operations, {_,Type}=Key) -> - Resets = - case Type:is_operation({reset, {}}) of - true -> - [{Clock, {reset, {}}} || {Clock, {remove, Key2}} <- Operations, Key == Key2]; - false -> [] - end, - Resets ++ [{Clock, NestedOp} || {Clock, {update, {Key2, NestedOp}}} <- Operations, Key == Key2]. - -nestedSpec(map_aw, Ops) -> spec(Ops); -nestedSpec(set_aw, Ops) -> prop_set_aw:spec(Ops); -nestedSpec(integer, Ops) -> prop_integer:spec(Ops). - -% normalizes operations (update-lists into single update-operations) -normalizeOp({Clock, {update, List}}, _) when is_list(List) -> - [{Clock, {update, X}} || X <- List]; -normalizeOp({Clock, {remove, List}}, _) when is_list(List) -> - [{Clock, {remove, X}} || X <- List]; -normalizeOp({Clock, {batch, {Updates, Removes}}}, _) -> - [{Clock, {update, X}} || X <- Updates] - ++ [{Clock, {remove, X}} || X <- Removes]; -normalizeOp({Clock, {reset, {}}}, Operations) -> - % reset is like removing all current keys - Map = spec(crdt_properties:subcontext(Clock, Operations)), - Keys = [Key || {Key, _Val} <- Map], - [{Clock, {remove, X}} || X <- Keys]; -normalizeOp(X, _) -> [X]. - - -% generates a random operation -op() -> ?SIZED(Size, op(Size)). -op(Size) -> - oneof([ - {update, nestedOp(Size)}, - {update, ?LET(L, list(nestedOp(Size div 2)), removeDuplicateKeys(L, []))}, - {remove, typed_key()}, - {remove, ?LET(L, list(typed_key()), lists:usort(L))}, - ?LET({Updates,Removes}, - {list(nestedOp(Size div 2)),list(typed_key())}, - begin - Removes2 = lists:usort(Removes), - Updates2 = removeDuplicateKeys(Updates, Removes2), - {batch, {Updates2, Removes2}} - 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( - [ - {{key(), integer}, prop_integer:op()}, - {{key(), set_aw}, prop_set_aw:op()} - ] - ++ - if - Size > 1 -> - [{{key(), map_aw}, ?LAZY(op(Size div 2))}]; - true -> [] - end - ). - -typed_key() -> {key(), crdt_type()}. - -crdt_type() -> - oneof([integer, set_aw, map_aw]). - -key() -> - oneof([a,b,c,d]). \ No newline at end of file From d223632efcd6b9ed9a7bdb0ea807607f84f01b6b Mon Sep 17 00:00:00 2001 From: Georges Younes Date: Fri, 26 Jan 2018 16:49:03 +0000 Subject: [PATCH 3/6] remove reset ops from mag-go --- TEST-file_antidote_crdt.app.xml | 207 ++++++++++++++++---------------- src/map_go.erl | 24 +--- test/prop_map_go.erl | 18 +-- 3 files changed, 112 insertions(+), 137 deletions(-) diff --git a/TEST-file_antidote_crdt.app.xml b/TEST-file_antidote_crdt.app.xml index 2f33b80..5270315 100644 --- a/TEST-file_antidote_crdt.app.xml +++ b/TEST-file_antidote_crdt.app.xml @@ -1,5 +1,5 @@ - + @@ -40,22 +40,22 @@ - + FatCnt0 = [] -Increment1 = {<<79,163,225,87,137,153,10,149,244,244,101,188,94,186,136,66,196, - 23,201,161>>, +Increment1 = {<<22,181,182,150,29,241,120,220,184,38,7,236,128,172,17,44,156, + 172,154,252>>, 5} -FatCnt1 = [{<<79,163,225,87,137,153,10,149,244,244,101,188,94,186,136,66,196, - 23,201,161>>, +FatCnt1 = [{<<22,181,182,150,29,241,120,220,184,38,7,236,128,172,17,44,156,172, + 154,252>>, 5}] -Decrement1 = {<<235,201,203,141,97,91,245,214,11,134,34,86,222,145,242,44,225, - 56,1,21>>, +Decrement1 = {<<62,111,233,67,40,87,22,36,233,120,72,31,206,79,123,73,147,72, + 175,175>>, -2} -FatCnt2 = [{<<79,163,225,87,137,153,10,149,244,244,101,188,94,186,136,66,196, - 23,201,161>>, +FatCnt2 = [{<<22,181,182,150,29,241,120,220,184,38,7,236,128,172,17,44,156,172, + 154,252>>, 5}, - {<<235,201,203,141,97,91,245,214,11,134,34,86,222,145,242,44,225,56, - 1,21>>, + {<<62,111,233,67,40,87,22,36,233,120,72,31,206,79,123,73,147,72,175, + 175>>, -2}] @@ -93,13 +93,14 @@ FatCnt2 = [{<<79,163,225,87,137,153,10,149,244,244,101,188,94,186,136,66,1 - Reset1Effect = {[<<69,2,50,41,144,119,5,212,38,255,168,248,50,161,9,27,6,151, - 170,12>>], + Reset1Effect = {[<<49,189,212,142,202,234,4,185,196,25,22,201,236,107,216,114, + 59,34,70,103>>], []} Enable1Effect = {[], - [<<69,2,50,41,144,119,5,212,38,255,168,248,50,161,9,27,6, - 151,170,12>>]} -Flag1a = [<<69,2,50,41,144,119,5,212,38,255,168,248,50,161,9,27,6,151,170,12>>] + [<<49,189,212,142,202,234,4,185,196,25,22,201,236,107,216, + 114,59,34,70,103>>]} +Flag1a = [<<49,189,212,142,202,234,4,185,196,25,22,201,236,107,216,114,59,34, + 70,103>>] Flag1b = [] @@ -116,26 +117,26 @@ Flag1b = [] - + Map0 = {dict,0,16,16,8,80,48, {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} Incr1 = {[{{a,counter_fat}, - {ok,{<<74,85,229,123,119,44,81,145,47,2,158,146,243,17,123,86,57, - 221,184,14>>, + {ok,{<<210,200,245,56,108,216,12,65,0,124,186,15,26,128,176,252,92, + 6,208,241>>, 1}}}], []} Map1a = {dict,1,16,16,8,80,48, {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[], [[{a,counter_fat}, - {<<74,85,229,123,119,44,81,145,47,2,158,146,243,17,123,86,57, - 221,184,14>>, + {<<210,200,245,56,108,216,12,65,0,124,186,15,26,128,176,252, + 92,6,208,241>>, 1}]]}}} Reset1 = {[], [{{a,counter_fat}, - {ok,[<<74,85,229,123,119,44,81,145,47,2,158,146,243,17,123,86, - 57,221,184,14>>]}}]} + {ok,[<<210,200,245,56,108,216,12,65,0,124,186,15,26,128,176, + 252,92,6,208,241>>]}}]} Map1b = {dict,0,16,16,8,80,48, {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} @@ -151,33 +152,33 @@ Map1d = {dict,0,16,16,8,80,48, {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} Incr2 = {[{{a,counter_fat}, - {ok,{<<101,22,237,250,225,241,253,26,122,69,55,5,87,251,196,216,44, - 158,2,50>>, + {ok,{<<112,241,178,86,101,182,204,230,101,222,220,255,33,16,84,124, + 31,151,37,245>>, 2}}}], []} Map1e = {dict,1,16,16,8,80,48, {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[], [[{a,counter_fat}, - {<<101,22,237,250,225,241,253,26,122,69,55,5,87,251,196,216, - 44,158,2,50>>, + {<<112,241,178,86,101,182,204,230,101,222,220,255,33,16,84, + 124,31,151,37,245>>, 2}]]}}} - + Map0 = [] Add1 = {[{{s,set_rw}, {ok,[{a,[], - [<<15,2,183,52,1,129,25,209,44,236,235,161,123,133,255,149, - 179,71,216,207>>], + [<<251,225,189,22,210,93,200,15,52,226,132,220,84,84,232, + 236,174,47,197,168>>], []}]}}], []} Map1a = [{{s,set_rw},[a]}] Reset1 = {[], [{{s,set_rw}, - {ok,[{a,[<<15,2,183,52,1,129,25,209,44,236,235,161,123,133,255, - 149,179,71,216,207>>], + {ok,[{a,[<<251,225,189,22,210,93,200,15,52,226,132,220,84,84,232, + 236,174,47,197,168>>], [],[]}]}}]} Map1b = [] Remove1 = {[],[{{s,set_rw},{ok,[]}}]} @@ -187,8 +188,8 @@ Reset2 = {[],[]} Map1d = [] Add2 = {[{{s,set_rw}, {ok,[{b,[], - [<<104,83,210,194,247,72,102,176,114,164,216,66,193,185,212, - 222,171,8,159,50>>], + [<<151,45,122,134,106,135,127,211,38,56,232,234,249,64,196, + 23,141,154,234,128>>], []}]}}], []} Map1e = [{{s,set_rw},[b]}] @@ -202,8 +203,8 @@ Map1e = [{{s,set_rw},[b]}] Add1 = {[{{a,map_rr}, {ok,{[{{a,set_rw}, {ok,[{a,[], - [<<109,155,120,190,214,108,38,209,143,129,220,25,171, - 148,92,229,137,170,212,213>>], + [<<115,172,32,208,170,88,99,101,153,173,160,16,255, + 216,179,58,233,125,1,231>>], []}]}}], []}}}], []} @@ -215,8 +216,8 @@ Map1a = {dict,1,16,16,8,80,48, {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, {{[[{a,set_rw}, {a, - {[<<109,155,120,190,214,108,38,209,143,129,220,25,171,148, - 92,229,137,170,212,213>>], + {[<<115,172,32,208,170,88,99,101,153,173,160,16,255,216, + 179,58,233,125,1,231>>], []}}]], [],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}}]], [],[],[],[],[],[]}}} @@ -224,8 +225,8 @@ Reset1 = {[], [{{a,map_rr}, {ok,{[], [{{a,set_rw}, - {ok,[{a,[<<109,155,120,190,214,108,38,209,143,129,220,25, - 171,148,92,229,137,170,212,213>>], + {ok,[{a,[<<115,172,32,208,170,88,99,101,153,173,160,16,255, + 216,179,58,233,125,1,231>>], [],[]}]}}]}}}]} Map1b = {dict,0,16,16,8,80,48, {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, @@ -288,27 +289,27 @@ Map1b = {dict,0,16,16,8,80,48, ResetEffect = [] Add1Effect = [{a,[], - [<<191,64,153,229,112,202,201,227,225,101,108,112,166,29,177, - 54,166,242,161,130>>], + [<<27,65,120,71,48,28,108,44,162,5,238,170,254,143,46,136, + 168,166,250,84>>], []}] Add2Effect = [{a,[], - [<<120,235,201,223,6,166,55,118,167,226,32,79,130,184,152,49, - 153,125,190,38>>], + [<<50,84,119,227,162,167,183,137,166,80,169,217,147,255,179, + 76,78,195,97,255>>], []}] Set1a = [] -Set1b = [{a,{[<<191,64,153,229,112,202,201,227,225,101,108,112,166,29,177,54, - 166,242,161,130>>], +Set1b = [{a,{[<<27,65,120,71,48,28,108,44,162,5,238,170,254,143,46,136,168, + 166,250,84>>], []}}] -Set2a = [{a,{[<<120,235,201,223,6,166,55,118,167,226,32,79,130,184,152,49,153, - 125,190,38>>], +Set2a = [{a,{[<<50,84,119,227,162,167,183,137,166,80,169,217,147,255,179,76, + 78,195,97,255>>], []}}] -Set2b = [{a,{[<<120,235,201,223,6,166,55,118,167,226,32,79,130,184,152,49,153, - 125,190,38>>], +Set2b = [{a,{[<<50,84,119,227,162,167,183,137,166,80,169,217,147,255,179,76, + 78,195,97,255>>], []}}] -Set2c = [{a,{[<<120,235,201,223,6,166,55,118,167,226,32,79,130,184,152,49,153, - 125,190,38>>, - <<191,64,153,229,112,202,201,227,225,101,108,112,166,29,177,54, - 166,242,161,130>>], +Set2c = [{a,{[<<50,84,119,227,162,167,183,137,166,80,169,217,147,255,179,76,78, + 195,97,255>>, + <<27,65,120,71,48,28,108,44,162,5,238,170,254,143,46,136,168, + 166,250,84>>], []}}] @@ -319,22 +320,22 @@ Set2c = [{a,{[<<120,235,201,223,6,166,55,118,167,226,32,79,130,184,152,49, Set0 = [] -Set1 = [{a,{[<<198,27,62,81,207,95,219,90,16,126,234,14,41,223,108,156,130, - 212,163,169>>], +Set1 = [{a,{[<<124,17,56,241,141,178,235,175,210,60,96,18,100,145,101,234,42, + 18,184,194>>], []}}] -Set2 = [{a,{[<<198,27,62,81,207,95,219,90,16,126,234,14,41,223,108,156,130, - 212,163,169>>], +Set2 = [{a,{[<<124,17,56,241,141,178,235,175,210,60,96,18,100,145,101,234,42, + 18,184,194>>], []}}, - {b,{[<<230,21,85,205,190,115,28,114,16,35,115,253,143,104,186,58,111, - 197,128,245>>], + {b,{[<<97,143,52,99,149,45,188,10,31,108,22,242,14,112,57,52,88,72,92, + 225>>], []}}] Add1Effect = [{a,[], - [<<198,27,62,81,207,95,219,90,16,126,234,14,41,223,108,156, - 130,212,163,169>>], + [<<124,17,56,241,141,178,235,175,210,60,96,18,100,145,101, + 234,42,18,184,194>>], []}] Add2Effect = [{b,[], - [<<230,21,85,205,190,115,28,114,16,35,115,253,143,104,186,58, - 111,197,128,245>>], + [<<97,143,52,99,149,45,188,10,31,108,22,242,14,112,57,52,88, + 72,92,225>>], []}] @@ -342,54 +343,54 @@ Add2Effect = [{b,[], ResetEffect = [] Add3Effect = [{b,[], - [<<16,255,41,104,203,117,206,26,91,147,191,149,153,124,83,38, - 186,23,20,108>>], + [<<36,172,36,141,1,102,64,170,146,86,115,165,158,115,10,140, + 127,14,56,196>>], []}] Set1a = [] -Set3a = [{b,{[<<16,255,41,104,203,117,206,26,91,147,191,149,153,124,83,38,186, - 23,20,108>>], +Set3a = [{b,{[<<36,172,36,141,1,102,64,170,146,86,115,165,158,115,10,140,127, + 14,56,196>>], []}}] -Set1b = [{b,{[<<16,255,41,104,203,117,206,26,91,147,191,149,153,124,83,38,186, - 23,20,108>>], +Set1b = [{b,{[<<36,172,36,141,1,102,64,170,146,86,115,165,158,115,10,140,127, + 14,56,196>>], []}}] Remove1Effect = [{b,[],[], - [<<118,7,168,5,190,218,129,243,36,149,33,76,127,116,157, - 243,230,6,70,79>>]}] + [<<92,90,92,28,31,208,51,212,154,67,204,40,62,243,188, + 98,250,225,103,241>>]}] Add3Effect = [{a,[], - [<<206,165,193,96,223,95,187,111,238,153,137,27,219,76,155, - 153,47,251,101,159>>], + [<<195,177,112,102,215,148,114,45,17,225,87,89,31,212,172,16, + 207,127,235,188>>], []}] Set1a = [{b,{[], - [<<118,7,168,5,190,218,129,243,36,149,33,76,127,116,157,243, - 230,6,70,79>>]}}] -Set3a = [{a,{[<<206,165,193,96,223,95,187,111,238,153,137,27,219,76,155,153, - 47,251,101,159>>], + [<<92,90,92,28,31,208,51,212,154,67,204,40,62,243,188,98,250, + 225,103,241>>]}}] +Set3a = [{a,{[<<195,177,112,102,215,148,114,45,17,225,87,89,31,212,172,16,207, + 127,235,188>>], []}}] -Set1b = [{a,{[<<206,165,193,96,223,95,187,111,238,153,137,27,219,76,155,153, - 47,251,101,159>>], +Set1b = [{a,{[<<195,177,112,102,215,148,114,45,17,225,87,89,31,212,172,16,207, + 127,235,188>>], []}}, {b,{[], - [<<118,7,168,5,190,218,129,243,36,149,33,76,127,116,157,243, - 230,6,70,79>>]}}] + [<<92,90,92,28,31,208,51,212,154,67,204,40,62,243,188,98,250, + 225,103,241>>]}}] - + Reset3Effect = [] Add2Effect = [{a,[], - [<<141,180,119,153,0,28,215,133,20,176,36,77,78,141,11,7,202, - 149,139,184>>], + [<<66,112,2,24,247,171,72,11,145,113,65,11,127,169,30,64,1, + 62,25,73>>], []}] -Set2a = [{a,{[<<141,180,119,153,0,28,215,133,20,176,36,77,78,141,11,7,202,149, - 139,184>>], +Set2a = [{a,{[<<66,112,2,24,247,171,72,11,145,113,65,11,127,169,30,64,1,62,25, + 73>>], []}}] Set3a = [] -Set3b = [{a,{[<<141,180,119,153,0,28,215,133,20,176,36,77,78,141,11,7,202,149, - 139,184>>], +Set3b = [{a,{[<<66,112,2,24,247,171,72,11,145,113,65,11,127,169,30,64,1,62,25, + 73>>], []}}] @@ -397,29 +398,29 @@ Set3b = [{a,{[<<141,180,119,153,0,28,215,133,20,176,36,77,78,141,11,7,202, Reset3Effect = [] Add2Effect = [{a,[], - [<<174,157,127,154,150,87,175,116,131,78,198,164,87,18,86, - 186,88,110,226,112>>], + [<<128,6,89,32,105,40,153,125,88,87,237,96,14,75,237,103,210, + 120,79,120>>], []}] -Set2a = [{a,{[<<174,157,127,154,150,87,175,116,131,78,198,164,87,18,86,186,88, - 110,226,112>>], +Set2a = [{a,{[<<128,6,89,32,105,40,153,125,88,87,237,96,14,75,237,103,210,120, + 79,120>>], []}}] Set3a = [] -Set3b = [{a,{[<<174,157,127,154,150,87,175,116,131,78,198,164,87,18,86,186,88, - 110,226,112>>], +Set3b = [{a,{[<<128,6,89,32,105,40,153,125,88,87,237,96,14,75,237,103,210,120, + 79,120>>], []}}] - - Reset2Effect = [{a,[<<208,100,243,7,159,179,18,124,253,35,49,77,225,110,192, - 193,129,14,142,184>>], + + Reset2Effect = [{a,[<<115,193,31,13,83,189,169,220,198,160,224,189,229,107,17, + 130,40,230,210,80>>], [],[]}] Add2Effect = [{a,[], - [<<208,100,243,7,159,179,18,124,253,35,49,77,225,110,192,193, - 129,14,142,184>>], + [<<115,193,31,13,83,189,169,220,198,160,224,189,229,107,17, + 130,40,230,210,80>>], []}] -Set2a = [{a,{[<<208,100,243,7,159,179,18,124,253,35,49,77,225,110,192,193,129, - 14,142,184>>], +Set2a = [{a,{[<<115,193,31,13,83,189,169,220,198,160,224,189,229,107,17,130, + 40,230,210,80>>], []}}] Set2b = [] diff --git a/src/map_go.erl b/src/map_go.erl index 421bc9f..417afca 100644 --- a/src/map_go.erl +++ b/src/map_go.erl @@ -41,8 +41,7 @@ -type map_go() :: dict:dict({Key::term(), Type::atom()}, NestedState::term()). -type map_go_op() :: {update, nested_op()} - | {update, [nested_op()]} - | {reset, {}}. + | {update, [nested_op()]}. -type nested_op() :: {{Key::term(), Type::atom() }, Op::term()}. -type map_go_effect() :: {update, nested_downstream()} @@ -72,20 +71,7 @@ downstream({update, {{Key, Type}, Op}}, CurrentMap) -> {ok, DownstreamOp} = Type:downstream(Op, CurrentValue), {ok, {update, {{Key, Type}, DownstreamOp}}}; downstream({update, Ops}, CurrentMap) when is_list(Ops) -> - {ok, {update, lists:map(fun(Op) -> {ok, DSOp} = downstream({update, Op}, CurrentMap), DSOp end, Ops)}}; -downstream({reset, {}}, CurrentMap) -> - % calls reset on all embedded keys which support reset - Reset = - fun({{Key, Type}, State}) -> - case Type:is_operation({reset, {}}) of - true -> - {ok, EmbeddedEffect} = Type:downstream({reset, {}}, State), - [{update, {{Key, Type}, EmbeddedEffect}}]; - false -> [] - end - end, - DownstreamResets = lists:flatmap(Reset, dict:to_list(CurrentMap)), - {ok, {update, DownstreamResets}}. + {ok, {update, lists:map(fun(Op) -> {ok, DSOp} = downstream({update, Op}, CurrentMap), DSOp end, Ops)}}. -spec update(map_go_effect(), map_go()) -> {ok, map_go()}. update({update, {{Key, Type}, Op}}, Map) -> @@ -129,7 +115,7 @@ is_operation(Operation) -> {update, Ops} when is_list(Ops) -> distinct([Key || {Key, _} <- Ops]) andalso lists:all(fun(Op) -> is_operation({update, Op}) end, Ops); - {reset, {}} -> true; + {reset, {}} -> false; _ -> false end. @@ -158,9 +144,7 @@ update2_test() -> Map1 = new(), {ok, Effect1} = downstream({update, [{{a, set_aw}, {add, a}}]}, Map1), {ok, Map2} = update(Effect1, Map1), - {ok, Effect2} = downstream({reset, {}}, Map2), - {ok, Map3} = update(Effect2, Map2), - ?assertEqual([{{a, set_aw}, []}], value(Map3)). + ?assertEqual([{{a, set_aw}, [a]}], value(Map2)). -endif. diff --git a/test/prop_map_go.erl b/test/prop_map_go.erl index c553dc5..77b9d65 100644 --- a/test/prop_map_go.erl +++ b/test/prop_map_go.erl @@ -38,14 +38,8 @@ spec(Operations1) -> NestedSpec = [{{Key,Type}, nestedSpec(Type, Ops)} || {{Key,Type}, Ops} <- GroupedByKey], lists:sort(NestedSpec). -nestedOps(Operations, {_,Type}=Key) -> - Resets = - case Type:is_operation({reset, {}}) of - true -> - [{Clock, {reset, {}}} || {Clock, {reset, {}}} <- Operations]; - false -> [] - end, - Resets ++ [{Clock, NestedOp} || {Clock, {update, {Key2, NestedOp}}} <- Operations, Key == Key2]. +nestedOps(Operations, Key) -> + [{Clock, NestedOp} || {Clock, {update, {Key2, NestedOp}}} <- Operations, Key == Key2]. nestedSpec(map_go, Ops) -> spec(Ops); nestedSpec(set_aw, Ops) -> prop_set_aw:spec(Ops); @@ -60,14 +54,10 @@ normalizeOp(X) -> [X]. % generates a random operation op() -> ?SIZED(Size, op(Size)). op(Size) -> - frequency([ - % nested updates - {10, {update, oneof([ + {update, oneof([ nestedOp(Size), ?LET(L, list(nestedOp(Size div 2)), removeDuplicateKeys(L, [])) - ])}}, - {1, {reset, {}}} - ]). + ])}. removeDuplicateKeys([], _) -> []; removeDuplicateKeys([{Key,Op}|Rest], Keys) -> From 9ac5d76e9f79f0ad8dff26f044b77d0c713c6384 Mon Sep 17 00:00:00 2001 From: Georges Younes Date: Mon, 5 Feb 2018 10:51:51 +0000 Subject: [PATCH 4/6] rename with prefix --- .gitignore | 3 +- TEST-file_antidote_crdt.app.xml | 429 ------------------ src/antidote_crdt.erl | 24 +- ...nter_b.erl => antidote_crdt_counter_b.erl} | 60 +-- ..._fat.erl => antidote_crdt_counter_fat.erl} | 4 +- ...er_pn.erl => antidote_crdt_counter_pn.erl} | 8 +- ...{flag_dw.erl => antidote_crdt_flag_dw.erl} | 28 +- ...{flag_ew.erl => antidote_crdt_flag_ew.erl} | 26 +- ...lper.erl => antidote_crdt_flag_helper.erl} | 2 +- src/{map_go.erl => antidote_crdt_map_go.erl} | 30 +- src/{map_rr.erl => antidote_crdt_map_rr.erl} | 46 +- ...lww.erl => antidote_crdt_register_lww.erl} | 12 +- ...r_mv.erl => antidote_crdt_register_mv.erl} | 32 +- src/{set_aw.erl => antidote_crdt_set_aw.erl} | 34 +- src/{set_go.erl => antidote_crdt_set_go.erl} | 14 +- src/{set_rw.erl => antidote_crdt_set_rw.erl} | 22 +- test/prop_counter_fat.erl | 2 +- test/prop_counter_pn.erl | 2 +- test/prop_flag_dw.erl | 2 +- test/prop_flag_ew.erl | 2 +- test/prop_map_go.erl | 14 +- test/prop_map_rr.erl | 22 +- test/prop_register_lww.erl | 2 +- test/prop_register_mv.erl | 2 +- test/prop_set_aw.erl | 2 +- test/prop_set_go.erl | 2 +- test/prop_set_rw.erl | 2 +- 27 files changed, 200 insertions(+), 628 deletions(-) delete mode 100644 TEST-file_antidote_crdt.app.xml rename src/{counter_b.erl => antidote_crdt_counter_b.erl} (80%) rename src/{counter_fat.erl => antidote_crdt_counter_fat.erl} (97%) rename src/{counter_pn.erl => antidote_crdt_counter_pn.erl} (96%) rename src/{flag_dw.erl => antidote_crdt_flag_dw.erl} (69%) rename src/{flag_ew.erl => antidote_crdt_flag_ew.erl} (75%) rename src/{flag_helper.erl => antidote_crdt_flag_helper.erl} (98%) rename src/{map_go.erl => antidote_crdt_map_go.erl} (78%) rename src/{map_rr.erl => antidote_crdt_map_rr.erl} (87%) rename src/{register_lww.erl => antidote_crdt_register_lww.erl} (83%) rename src/{register_mv.erl => antidote_crdt_register_mv.erl} (77%) rename src/{set_aw.erl => antidote_crdt_set_aw.erl} (90%) rename src/{set_go.erl => antidote_crdt_set_go.erl} (80%) rename src/{set_rw.erl => antidote_crdt_set_rw.erl} (94%) diff --git a/.gitignore b/.gitignore index 5200b23..1c908bd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ TEST-file_"antidote_crdt.app".xml *.swp src/*.swp test/*.swp -*.beam \ No newline at end of file +*.beam +TEST-file_antidote_crdt.app.xml \ No newline at end of file diff --git a/TEST-file_antidote_crdt.app.xml b/TEST-file_antidote_crdt.app.xml deleted file mode 100644 index 5270315..0000000 --- a/TEST-file_antidote_crdt.app.xml +++ /dev/null @@ -1,429 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FatCnt0 = [] -Increment1 = {<<22,181,182,150,29,241,120,220,184,38,7,236,128,172,17,44,156, - 172,154,252>>, - 5} -FatCnt1 = [{<<22,181,182,150,29,241,120,220,184,38,7,236,128,172,17,44,156,172, - 154,252>>, - 5}] -Decrement1 = {<<62,111,233,67,40,87,22,36,233,120,72,31,206,79,123,73,147,72, - 175,175>>, - -2} -FatCnt2 = [{<<22,181,182,150,29,241,120,220,184,38,7,236,128,172,17,44,156,172, - 154,252>>, - 5}, - {<<62,111,233,67,40,87,22,36,233,120,72,31,206,79,123,73,147,72,175, - 175>>, - -2}] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Reset1Effect = {[<<49,189,212,142,202,234,4,185,196,25,22,201,236,107,216,114, - 59,34,70,103>>], - []} -Enable1Effect = {[], - [<<49,189,212,142,202,234,4,185,196,25,22,201,236,107,216, - 114,59,34,70,103>>]} -Flag1a = [<<49,189,212,142,202,234,4,185,196,25,22,201,236,107,216,114,59,34, - 70,103>>] -Flag1b = [] - - - - - - - - - - - - - - - - - Map0 = {dict,0,16,16,8,80,48, - {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, - {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} -Incr1 = {[{{a,counter_fat}, - {ok,{<<210,200,245,56,108,216,12,65,0,124,186,15,26,128,176,252,92, - 6,208,241>>, - 1}}}], - []} -Map1a = {dict,1,16,16,8,80,48, - {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, - {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[], - [[{a,counter_fat}, - {<<210,200,245,56,108,216,12,65,0,124,186,15,26,128,176,252, - 92,6,208,241>>, - 1}]]}}} -Reset1 = {[], - [{{a,counter_fat}, - {ok,[<<210,200,245,56,108,216,12,65,0,124,186,15,26,128,176, - 252,92,6,208,241>>]}}]} -Map1b = {dict,0,16,16,8,80,48, - {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, - {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} -Remove1 = {[],[{{a,counter_fat},{ok,[]}}]} -Map2a = {dict,0,16,16,8,80,48, - {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, - {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} -Map1c = {dict,0,16,16,8,80,48, - {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, - {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} -Reset2 = {[],[]} -Map1d = {dict,0,16,16,8,80,48, - {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, - {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} -Incr2 = {[{{a,counter_fat}, - {ok,{<<112,241,178,86,101,182,204,230,101,222,220,255,33,16,84,124, - 31,151,37,245>>, - 2}}}], - []} -Map1e = {dict,1,16,16,8,80,48, - {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, - {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[], - [[{a,counter_fat}, - {<<112,241,178,86,101,182,204,230,101,222,220,255,33,16,84, - 124,31,151,37,245>>, - 2}]]}}} - - - - - Map0 = [] -Add1 = {[{{s,set_rw}, - {ok,[{a,[], - [<<251,225,189,22,210,93,200,15,52,226,132,220,84,84,232, - 236,174,47,197,168>>], - []}]}}], - []} -Map1a = [{{s,set_rw},[a]}] -Reset1 = {[], - [{{s,set_rw}, - {ok,[{a,[<<251,225,189,22,210,93,200,15,52,226,132,220,84,84,232, - 236,174,47,197,168>>], - [],[]}]}}]} -Map1b = [] -Remove1 = {[],[{{s,set_rw},{ok,[]}}]} -Map2a = [] -Map1c = [] -Reset2 = {[],[]} -Map1d = [] -Add2 = {[{{s,set_rw}, - {ok,[{b,[], - [<<151,45,122,134,106,135,127,211,38,56,232,234,249,64,196, - 23,141,154,234,128>>], - []}]}}], - []} -Map1e = [{{s,set_rw},[b]}] - - - - - Map0 = {dict,0,16,16,8,80,48, - {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, - {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} -Add1 = {[{{a,map_rr}, - {ok,{[{{a,set_rw}, - {ok,[{a,[], - [<<115,172,32,208,170,88,99,101,153,173,160,16,255, - 216,179,58,233,125,1,231>>], - []}]}}], - []}}}], - []} -Map1a = {dict,1,16,16,8,80,48, - {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, - {{[],[],[],[],[],[],[],[],[], - [[{a,map_rr}| - {dict,1,16,16,8,80,48, - {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, - {{[[{a,set_rw}, - {a, - {[<<115,172,32,208,170,88,99,101,153,173,160,16,255,216, - 179,58,233,125,1,231>>], - []}}]], - [],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}}]], - [],[],[],[],[],[]}}} -Reset1 = {[], - [{{a,map_rr}, - {ok,{[], - [{{a,set_rw}, - {ok,[{a,[<<115,172,32,208,170,88,99,101,153,173,160,16,255, - 216,179,58,233,125,1,231>>], - [],[]}]}}]}}}]} -Map1b = {dict,0,16,16,8,80,48, - {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, - {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} - - - - - Map0 = {dict,0,16,16,8,80,48, - {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, - {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} -Add1 = {[{{b,map_rr},{ok,{[],[{{a,set_rw},{ok,[]}}]}}}],[]} -Map1a = {dict,0,16,16,8,80,48, - {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, - {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} -Remove2 = {[],[{{b,map_rr},{ok,{[],[]}}}]} -Map1b = {dict,0,16,16,8,80,48, - {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}, - {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}} - - - - - M3 state = [] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ResetEffect = [] -Add1Effect = [{a,[], - [<<27,65,120,71,48,28,108,44,162,5,238,170,254,143,46,136, - 168,166,250,84>>], - []}] -Add2Effect = [{a,[], - [<<50,84,119,227,162,167,183,137,166,80,169,217,147,255,179, - 76,78,195,97,255>>], - []}] -Set1a = [] -Set1b = [{a,{[<<27,65,120,71,48,28,108,44,162,5,238,170,254,143,46,136,168, - 166,250,84>>], - []}}] -Set2a = [{a,{[<<50,84,119,227,162,167,183,137,166,80,169,217,147,255,179,76, - 78,195,97,255>>], - []}}] -Set2b = [{a,{[<<50,84,119,227,162,167,183,137,166,80,169,217,147,255,179,76, - 78,195,97,255>>], - []}}] -Set2c = [{a,{[<<50,84,119,227,162,167,183,137,166,80,169,217,147,255,179,76,78, - 195,97,255>>, - <<27,65,120,71,48,28,108,44,162,5,238,170,254,143,46,136,168, - 166,250,84>>], - []}}] - - - - - - - - - Set0 = [] -Set1 = [{a,{[<<124,17,56,241,141,178,235,175,210,60,96,18,100,145,101,234,42, - 18,184,194>>], - []}}] -Set2 = [{a,{[<<124,17,56,241,141,178,235,175,210,60,96,18,100,145,101,234,42, - 18,184,194>>], - []}}, - {b,{[<<97,143,52,99,149,45,188,10,31,108,22,242,14,112,57,52,88,72,92, - 225>>], - []}}] -Add1Effect = [{a,[], - [<<124,17,56,241,141,178,235,175,210,60,96,18,100,145,101, - 234,42,18,184,194>>], - []}] -Add2Effect = [{b,[], - [<<97,143,52,99,149,45,188,10,31,108,22,242,14,112,57,52,88, - 72,92,225>>], - []}] - - - - - ResetEffect = [] -Add3Effect = [{b,[], - [<<36,172,36,141,1,102,64,170,146,86,115,165,158,115,10,140, - 127,14,56,196>>], - []}] -Set1a = [] -Set3a = [{b,{[<<36,172,36,141,1,102,64,170,146,86,115,165,158,115,10,140,127, - 14,56,196>>], - []}}] -Set1b = [{b,{[<<36,172,36,141,1,102,64,170,146,86,115,165,158,115,10,140,127, - 14,56,196>>], - []}}] - - - - - Remove1Effect = [{b,[],[], - [<<92,90,92,28,31,208,51,212,154,67,204,40,62,243,188, - 98,250,225,103,241>>]}] -Add3Effect = [{a,[], - [<<195,177,112,102,215,148,114,45,17,225,87,89,31,212,172,16, - 207,127,235,188>>], - []}] -Set1a = [{b,{[], - [<<92,90,92,28,31,208,51,212,154,67,204,40,62,243,188,98,250, - 225,103,241>>]}}] -Set3a = [{a,{[<<195,177,112,102,215,148,114,45,17,225,87,89,31,212,172,16,207, - 127,235,188>>], - []}}] -Set1b = [{a,{[<<195,177,112,102,215,148,114,45,17,225,87,89,31,212,172,16,207, - 127,235,188>>], - []}}, - {b,{[], - [<<92,90,92,28,31,208,51,212,154,67,204,40,62,243,188,98,250, - 225,103,241>>]}}] - - - - - Reset3Effect = [] -Add2Effect = [{a,[], - [<<66,112,2,24,247,171,72,11,145,113,65,11,127,169,30,64,1, - 62,25,73>>], - []}] -Set2a = [{a,{[<<66,112,2,24,247,171,72,11,145,113,65,11,127,169,30,64,1,62,25, - 73>>], - []}}] -Set3a = [] -Set3b = [{a,{[<<66,112,2,24,247,171,72,11,145,113,65,11,127,169,30,64,1,62,25, - 73>>], - []}}] - - - - - Reset3Effect = [] -Add2Effect = [{a,[], - [<<128,6,89,32,105,40,153,125,88,87,237,96,14,75,237,103,210, - 120,79,120>>], - []}] -Set2a = [{a,{[<<128,6,89,32,105,40,153,125,88,87,237,96,14,75,237,103,210,120, - 79,120>>], - []}}] -Set3a = [] -Set3b = [{a,{[<<128,6,89,32,105,40,153,125,88,87,237,96,14,75,237,103,210,120, - 79,120>>], - []}}] - - - - - Reset2Effect = [{a,[<<115,193,31,13,83,189,169,220,198,160,224,189,229,107,17, - 130,40,230,210,80>>], - [],[]}] -Add2Effect = [{a,[], - [<<115,193,31,13,83,189,169,220,198,160,224,189,229,107,17, - 130,40,230,210,80>>], - []}] -Set2a = [{a,{[<<115,193,31,13,83,189,169,220,198,160,224,189,229,107,17,130, - 40,230,210,80>>], - []}}] -Set2b = [] - - - - diff --git a/src/antidote_crdt.erl b/src/antidote_crdt.erl index 5bf5c63..dc4555c 100644 --- a/src/antidote_crdt.erl +++ b/src/antidote_crdt.erl @@ -44,18 +44,18 @@ -include("antidote_crdt.hrl"). --define(CRDTS, [counter_pn, - counter_b, - counter_fat, - flag_ew, - flag_dw, - set_go, - set_aw, - set_rw, - register_lww, - register_mv, - map_go, - map_rr]). +-define(CRDTS, [antidote_crdt_counter_pn, + antidote_crdt_counter_b, + antidote_crdt_counter_fat, + antidote_crdt_flag_ew, + antidote_crdt_flag_dw, + antidote_crdt_set_go, + antidote_crdt_set_aw, + antidote_crdt_set_rw, + antidote_crdt_register_lww, + antidote_crdt_register_mv, + antidote_crdt_map_go, + antidote_crdt_map_rr]). -export([is_type/1 ]). diff --git a/src/counter_b.erl b/src/antidote_crdt_counter_b.erl similarity index 80% rename from src/counter_b.erl rename to src/antidote_crdt_counter_b.erl index 434eabd..4c70356 100644 --- a/src/counter_b.erl +++ b/src/antidote_crdt_counter_b.erl @@ -1,7 +1,7 @@ %% -*- coding: utf-8 -*- %% -------------------------------------------------------------------------- %% -%% counter_b: A convergent, replicated, operation-based bounded counter. +%% antidote_crdt_counter_b: A convergent, replicated, operation-based bounded counter. %% %% -------------------------------------------------------------------------- @@ -12,7 +12,7 @@ %% All operations on this CRDT are monotonic and do not keep extra tombstones. %% @end --module(counter_b). +-module(antidote_crdt_counter_b). -behaviour(antidote_crdt). @@ -40,23 +40,23 @@ -include_lib("eunit/include/eunit.hrl"). -endif. --export_type([counter_b/0, binary_counter_b/0, counter_b_op/0, id/0]). +-export_type([antidote_crdt_counter_b/0, binary_antidote_crdt_counter_b/0, antidote_crdt_counter_b_op/0, id/0]). --opaque counter_b() :: {orddict:orddict(), orddict:orddict()}. --type binary_counter_b() :: binary(). --type counter_b_op() :: counter_b_anon_op() | counter_b_src_op(). --type counter_b_anon_op() :: {transfer, {pos_integer(), id(), id()}} | +-opaque antidote_crdt_counter_b() :: {orddict:orddict(), orddict:orddict()}. +-type binary_antidote_crdt_counter_b() :: binary(). +-type antidote_crdt_counter_b_op() :: antidote_crdt_counter_b_anon_op() | antidote_crdt_counter_b_src_op(). +-type antidote_crdt_counter_b_anon_op() :: {transfer, {pos_integer(), id(), id()}} | {increment, {pos_integer(), id()}} | {decrement, {pos_integer(), id()}}. --type counter_b_src_op() :: {counter_b_anon_op(), id()}. +-type antidote_crdt_counter_b_src_op() :: {antidote_crdt_counter_b_anon_op(), id()}. -opaque id() :: term. %% A replica's identifier. -%% @doc Return a new, empty `counter_b()'. --spec new() -> counter_b(). +%% @doc Return a new, empty `antidote_crdt_counter_b()'. +-spec new() -> antidote_crdt_counter_b(). new() -> {orddict:new(), orddict:new()}. -%% @doc Return the available permissions of replica `Id' in a `counter_b()'. --spec localPermissions(id(), counter_b()) -> non_neg_integer(). +%% @doc Return the available permissions of replica `Id' in a `antidote_crdt_counter_b()'. +-spec localPermissions(id(), antidote_crdt_counter_b()) -> non_neg_integer(). localPermissions(Id, {P, D}) -> Received = lists:foldl( fun( @@ -88,8 +88,8 @@ localPermissions(Id, {P, D}) -> Received - Granted end. -%% @doc Return the total available permissions in a `counter_b()'. --spec permissions(counter_b()) -> non_neg_integer(). +%% @doc Return the total available permissions in a `antidote_crdt_counter_b()'. +-spec permissions(antidote_crdt_counter_b()) -> non_neg_integer(). permissions({P, D}) -> TotalIncrements = orddict:fold( fun @@ -105,8 +105,8 @@ permissions({P, D}) -> end, 0, D), TotalIncrements - TotalDecrements. -%% @doc Return the read value of a given `counter_b()', itself. --spec value(counter_b()) -> counter_b(). +%% @doc Return the read value of a given `antidote_crdt_counter_b()', itself. +-spec value(antidote_crdt_counter_b()) -> antidote_crdt_counter_b(). value(Counter) -> Counter. %% @doc Generate a downstream operation. @@ -114,13 +114,13 @@ value(Counter) -> Counter. %% which specify the operation and amount, or `{transfer, pos_integer(), id()}' %% that additionally specifies the target replica. %% The second parameter is an `actor()' who identifies the source replica, -%% and the third parameter is a `counter_b()' which holds the current snapshot. +%% and the third parameter is a `antidote_crdt_counter_b()' which holds the current snapshot. %% %% Return a tuple containing the operation and source replica. %% This operation fails and returns `{error, no_permissions}' %% if it tries to consume resources unavailable to the source replica %% (which prevents logging of forbidden attempts). --spec downstream(counter_b_op(), counter_b()) -> {ok, term()} | {error, no_permissions}. +-spec downstream(antidote_crdt_counter_b_op(), antidote_crdt_counter_b()) -> {ok, term()} | {error, no_permissions}. downstream({increment, {V, Actor}}, _Counter) when is_integer(V), V > 0 -> {ok, {{increment, V}, Actor}}; downstream({decrement, {V, Actor}}, Counter) when is_integer(V), V > 0 -> @@ -134,11 +134,11 @@ generate_downstream_check(Op, Actor, Counter, V) -> Available < V -> {error, no_permissions} end. -%% @doc Update a `counter_b()' with a downstream operation, +%% @doc Update a `antidote_crdt_counter_b()' with a downstream operation, %% usually created with `generate_downstream'. %% -%% Return the resulting `counter_b()' after applying the operation. --spec update(term(), counter_b()) -> {ok, counter_b()}. +%% Return the resulting `antidote_crdt_counter_b()' after applying the operation. +-spec update(term(), antidote_crdt_counter_b()) -> {ok, antidote_crdt_counter_b()}. update({{increment, V}, Id}, Counter) -> increment(Id, V, Counter); update({{decrement, V}, Id}, Counter) -> @@ -158,12 +158,12 @@ decrement(Id, V, {P, D}) -> transfer(From, To, V, {P, D}) -> {ok, {orddict:update_counter({From, To}, V, P), D}}. -%% doc Return the binary representation of a `counter_b()'. --spec to_binary(counter_b()) -> binary(). +%% doc Return the binary representation of a `antidote_crdt_counter_b()'. +-spec to_binary(antidote_crdt_counter_b()) -> binary(). to_binary(C) -> term_to_binary(C). -%% doc Return a `counter_b()' from its binary representation. --spec from_binary(binary()) -> {ok, counter_b()}. +%% doc Return a `antidote_crdt_counter_b()' from its binary representation. +-spec from_binary(binary()) -> {ok, antidote_crdt_counter_b()}. from_binary(<>) -> {ok, binary_to_term(B)}. %% @doc The following operation verifies @@ -199,7 +199,7 @@ apply_op(Op, Counter) -> {ok, NewCounter} = update(OP_DS, Counter), NewCounter. -%% Tests creating a new `counter_b()'. +%% Tests creating a new `antidote_crdt_counter_b()'. new_test() -> ?assertEqual({[], []}, new()). @@ -271,22 +271,22 @@ transfer_test() -> %% Tests the function `value()'. value_test() -> - %% Test on `counter_b()' resulting from applying all kinds of operation. + %% Test on `antidote_crdt_counter_b()' resulting from applying all kinds of operation. Counter0 = new(), Counter1 = apply_op({increment, {10, r1}}, Counter0), Counter2 = apply_op({decrement, {6, r1}}, Counter1), Counter3 = apply_op({transfer, {2, r2, r1}}, Counter2), - %% Assert `value()' returns `counter_b()' itself. + %% Assert `value()' returns `antidote_crdt_counter_b()' itself. ?assertEqual(Counter3, value(Counter3)). %% Tests serialization functions `to_binary()' and `from_binary()'. binary_test() -> - %% Test on `counter_b()' resulting from applying all kinds of operation. + %% Test on `antidote_crdt_counter_b()' resulting from applying all kinds of operation. Counter0 = new(), Counter1 = apply_op({increment, {10, r1}}, Counter0), Counter2 = apply_op({decrement, {6, r1}}, Counter1), Counter3 = apply_op({transfer, {2, r2, r1}}, Counter2), - %% Assert marshaling and unmarshaling holds the same `counter_b()'. + %% Assert marshaling and unmarshaling holds the same `antidote_crdt_counter_b()'. B = to_binary(Counter3), ?assertEqual({ok, Counter3}, from_binary(B)). diff --git a/src/counter_fat.erl b/src/antidote_crdt_counter_fat.erl similarity index 97% rename from src/counter_fat.erl rename to src/antidote_crdt_counter_fat.erl index 2d2b840..9bf7738 100644 --- a/src/counter_fat.erl +++ b/src/antidote_crdt_counter_fat.erl @@ -18,7 +18,7 @@ %% %% ------------------------------------------------------------------- -%% counter_fat: A convergent, replicated, operation based Fat Counter +%% antidote_crdt_counter_fat: A convergent, replicated, operation based Fat Counter %% The state of this fat counter is list of pairs where each pair is an integer %% and a related token. %% Basically when the counter recieves {increment, N} or {decrement, N} it generates @@ -28,7 +28,7 @@ %% functionaility, On reset(), all seen tokens are removed. %% link to paper: http://haslab.uminho.pt/cbm/files/a3-younes.pdf --module(counter_fat). +-module(antidote_crdt_counter_fat). -behaviour(antidote_crdt). diff --git a/src/counter_pn.erl b/src/antidote_crdt_counter_pn.erl similarity index 96% rename from src/counter_pn.erl rename to src/antidote_crdt_counter_pn.erl index af5bee1..703b412 100644 --- a/src/counter_pn.erl +++ b/src/antidote_crdt_counter_pn.erl @@ -18,10 +18,10 @@ %% %% ------------------------------------------------------------------- -%% counter_pn: A convergent, replicated, operation +%% antidote_crdt_counter_pn: A convergent, replicated, operation %% based PN-Counter --module(counter_pn). +-module(antidote_crdt_counter_pn). -behaviour(antidote_crdt). @@ -47,11 +47,11 @@ {decrement, integer()}. -type effect() :: integer(). -%% @doc Create a new, empty 'counter_pn' +%% @doc Create a new, empty 'antidote_crdt_counter_pn' new() -> 0. -%% @doc Create 'counter_pn' with initial value +%% @doc Create 'antidote_crdt_counter_pn' with initial value -spec new(integer()) -> state(). new(Value) when is_integer(Value) -> Value; diff --git a/src/flag_dw.erl b/src/antidote_crdt_flag_dw.erl similarity index 69% rename from src/flag_dw.erl rename to src/antidote_crdt_flag_dw.erl index 649d10c..c052e21 100644 --- a/src/flag_dw.erl +++ b/src/antidote_crdt_flag_dw.erl @@ -22,7 +22,7 @@ %% An operation-based Disable-wins Flag CRDT. %% @end --module(flag_dw). +-module(antidote_crdt_flag_dw). %% Callbacks -export([ new/0, @@ -46,39 +46,39 @@ -define(TAG, 77). -define(V1_VERS, 1). --export_type([flag_dw/0]). --opaque flag_dw() :: {flag_helper:tokens(), flag_helper:tokens()}. +-export_type([antidote_crdt_flag_dw/0]). +-opaque antidote_crdt_flag_dw() :: {antidote_crdt_flag_helper:tokens(), antidote_crdt_flag_helper:tokens()}. %% SeenTokens, NewEnableTokens, NewDisableTokens --type downstream_op() :: {flag_helper:tokens(), flag_helper:tokens(), flag_helper:tokens()}. +-type downstream_op() :: {antidote_crdt_flag_helper:tokens(), antidote_crdt_flag_helper:tokens(), antidote_crdt_flag_helper:tokens()}. --spec new() -> flag_dw(). +-spec new() -> antidote_crdt_flag_dw(). new() -> {[], []}. --spec value(flag_dw()) -> boolean(). +-spec value(antidote_crdt_flag_dw()) -> boolean(). value({EnableTokens, DisableTokens}) -> DisableTokens == [] andalso EnableTokens =/= []. --spec downstream(flag_helper:op(), flag_dw()) -> {ok, downstream_op()}. +-spec downstream(antidote_crdt_flag_helper:op(), antidote_crdt_flag_dw()) -> {ok, downstream_op()}. downstream({disable, {}}, {EnableTokens, DisableTokens}) -> - {ok, {EnableTokens ++ DisableTokens, [], [flag_helper:unique()]}}; + {ok, {EnableTokens ++ DisableTokens, [], [antidote_crdt_flag_helper:unique()]}}; downstream({enable, {}}, {EnableTokens, DisableTokens}) -> - {ok, {EnableTokens ++ DisableTokens, [flag_helper:unique()], []}}; + {ok, {EnableTokens ++ DisableTokens, [antidote_crdt_flag_helper:unique()], []}}; downstream({reset, {}}, {EnableTokens, DisableTokens}) -> {ok, {EnableTokens ++ DisableTokens, [], []}}. --spec update(downstream_op(), flag_dw()) -> {ok, flag_dw()}. +-spec update(downstream_op(), antidote_crdt_flag_dw()) -> {ok, antidote_crdt_flag_dw()}. update({SeenTokens, NewEnableTokens, NewDisableTokens}, {CurrentEnableTokens, CurrentDisableTokens}) -> FinalEnableTokens = (CurrentEnableTokens ++ NewEnableTokens) -- SeenTokens, FinalDisableTokens = (CurrentDisableTokens ++ NewDisableTokens) -- SeenTokens, {ok, {FinalEnableTokens, FinalDisableTokens}}. --spec equal(flag_dw(), flag_dw()) -> boolean(). +-spec equal(antidote_crdt_flag_dw(), antidote_crdt_flag_dw()) -> boolean(). equal(Flag1, Flag2) -> Flag1 == Flag2. --spec to_binary(flag_dw()) -> flag_helper:binary_flag(). +-spec to_binary(antidote_crdt_flag_dw()) -> antidote_crdt_flag_helper:binary_flag(). to_binary(Flag) -> %% @TODO something smarter <>. @@ -87,12 +87,12 @@ from_binary(<>) -> %% @TODO something smarter {ok, binary_to_term(Bin)}. -is_operation(A) -> flag_helper:is_operation(A). +is_operation(A) -> antidote_crdt_flag_helper:is_operation(A). is_bottom(Flag) -> Flag == new(). -require_state_downstream(A) -> flag_helper:require_state_downstream(A). +require_state_downstream(A) -> antidote_crdt_flag_helper:require_state_downstream(A). %% =================================================================== diff --git a/src/flag_ew.erl b/src/antidote_crdt_flag_ew.erl similarity index 75% rename from src/flag_ew.erl rename to src/antidote_crdt_flag_ew.erl index b1e190e..37db0ba 100644 --- a/src/flag_ew.erl +++ b/src/antidote_crdt_flag_ew.erl @@ -22,7 +22,7 @@ %% An operation-based Enable-wins Flag CRDT. %% @end --module(flag_ew). +-module(antidote_crdt_flag_ew). %% Callbacks -export([ new/0, @@ -46,38 +46,38 @@ -define(TAG, 77). -define(V1_VERS, 1). --export_type([flag_ew/0]). --opaque flag_ew() :: flag_helper:flag(). +-export_type([antidote_crdt_flag_ew/0]). +-opaque antidote_crdt_flag_ew() :: antidote_crdt_flag_helper:flag(). %% SeenTokens, NewTokens --type downstream_op() :: {flag_helper:tokens(), flag_helper:tokens()}. +-type downstream_op() :: {antidote_crdt_flag_helper:tokens(), antidote_crdt_flag_helper:tokens()}. --spec new() -> flag_ew(). +-spec new() -> antidote_crdt_flag_ew(). new() -> []. --spec value(flag_ew()) -> boolean(). +-spec value(antidote_crdt_flag_ew()) -> boolean(). value(EnableTokens) -> EnableTokens =/= []. --spec downstream(flag_helper:op(), flag_ew()) -> {ok, downstream_op()}. +-spec downstream(antidote_crdt_flag_helper:op(), antidote_crdt_flag_ew()) -> {ok, downstream_op()}. downstream({disable, {}}, Tokens) -> {ok, {Tokens, []}}; downstream({enable, {}}, Tokens) -> - {ok, {Tokens, [flag_helper:unique()]}}; + {ok, {Tokens, [antidote_crdt_flag_helper:unique()]}}; downstream({reset, {}}, Tokens) -> {ok, {Tokens, []}}. --spec update(downstream_op(), flag_ew()) -> {ok, flag_ew()}. +-spec update(downstream_op(), antidote_crdt_flag_ew()) -> {ok, antidote_crdt_flag_ew()}. update({SeenTokens, NewTokens}, CurrentTokens) -> FinalTokens = (CurrentTokens ++ NewTokens) -- SeenTokens, {ok, FinalTokens}. --spec equal(flag_ew(), flag_ew()) -> boolean(). +-spec equal(antidote_crdt_flag_ew(), antidote_crdt_flag_ew()) -> boolean(). equal(Flag1, Flag2) -> Flag1 == Flag2. % Everything inside is ordered, so this should work --spec to_binary(flag_ew()) -> flag_helper:binary_flag(). +-spec to_binary(antidote_crdt_flag_ew()) -> antidote_crdt_flag_helper:binary_flag(). to_binary(Flag) -> %% @TODO something smarter <>. @@ -86,12 +86,12 @@ from_binary(<>) -> %% @TODO something smarter {ok, binary_to_term(Bin)}. -is_operation(A) -> flag_helper:is_operation(A). +is_operation(A) -> antidote_crdt_flag_helper:is_operation(A). is_bottom(Flag) -> Flag == new(). -require_state_downstream(A) -> flag_helper:require_state_downstream(A). +require_state_downstream(A) -> antidote_crdt_flag_helper:require_state_downstream(A). %% =================================================================== %% EUnit tests diff --git a/src/flag_helper.erl b/src/antidote_crdt_flag_helper.erl similarity index 98% rename from src/flag_helper.erl rename to src/antidote_crdt_flag_helper.erl index 25b64d9..a89c44e 100644 --- a/src/flag_helper.erl +++ b/src/antidote_crdt_flag_helper.erl @@ -22,7 +22,7 @@ %% A helper for operation-based flags, enable wins flag and disable wins flag. %% @end --module(flag_helper). +-module(antidote_crdt_flag_helper). %% Callbacks diff --git a/src/map_go.erl b/src/antidote_crdt_map_go.erl similarity index 78% rename from src/map_go.erl rename to src/antidote_crdt_map_go.erl index 417afca..0c42a61 100644 --- a/src/map_go.erl +++ b/src/antidote_crdt_map_go.erl @@ -18,14 +18,14 @@ %% %% ------------------------------------------------------------------- -%% @doc module map_go - A grow-only map +%% @doc module antidote_crdt_map_go - A grow-only map %% %% This map simply forwards all operations to the embedded CRDTs. %% There is no real remove-operation. %% %% The reset operation, forwards the reset to all values in the map. --module(map_go). +-module(antidote_crdt_map_go). -behaviour(antidote_crdt). @@ -38,30 +38,30 @@ -endif. --type map_go() :: dict:dict({Key::term(), Type::atom()}, NestedState::term()). --type map_go_op() :: +-type antidote_crdt_map_go() :: dict:dict({Key::term(), Type::atom()}, NestedState::term()). +-type antidote_crdt_map_go_op() :: {update, nested_op()} | {update, [nested_op()]}. -type nested_op() :: {{Key::term(), Type::atom() }, Op::term()}. --type map_go_effect() :: +-type antidote_crdt_map_go_effect() :: {update, nested_downstream()} | {update, [nested_downstream()]}. -type nested_downstream() :: {{Key::term(), Type::atom() }, Op::term()}. --spec new() -> map_go(). +-spec new() -> antidote_crdt_map_go(). new() -> dict:new(). --spec value(map_go()) -> [{{Key::term(), Type::atom()}, Value::term()}]. +-spec value(antidote_crdt_map_go()) -> [{{Key::term(), Type::atom()}, Value::term()}]. value(Map) -> lists:sort([{{Key, Type}, Type:value(Value)} || {{Key, Type}, Value} <- dict:to_list(Map)]). --spec require_state_downstream(map_go_op()) -> boolean(). +-spec require_state_downstream(antidote_crdt_map_go_op()) -> boolean(). require_state_downstream(_Op) -> true. --spec downstream(map_go_op(), map_go()) -> {ok, map_go_effect()}. +-spec downstream(antidote_crdt_map_go_op(), antidote_crdt_map_go()) -> {ok, antidote_crdt_map_go_effect()}. downstream({update, {{Key, Type}, Op}}, CurrentMap) -> % TODO could be optimized for some types CurrentValue = case dict:is_key({Key, Type}, CurrentMap) of @@ -73,7 +73,7 @@ downstream({update, {{Key, Type}, Op}}, CurrentMap) -> downstream({update, Ops}, CurrentMap) when is_list(Ops) -> {ok, {update, lists:map(fun(Op) -> {ok, DSOp} = downstream({update, Op}, CurrentMap), DSOp end, Ops)}}. --spec update(map_go_effect(), map_go()) -> {ok, map_go()}. +-spec update(antidote_crdt_map_go_effect(), antidote_crdt_map_go()) -> {ok, antidote_crdt_map_go()}. update({update, {{Key, Type}, Op}}, Map) -> case dict:is_key({Key, Type}, Map) of true -> {ok, dict:update({Key, Type}, fun(V) -> {ok, Value} = Type:update(Op, V), Value end, Map)}; @@ -135,16 +135,16 @@ new_test() -> update_test() -> Map1 = new(), - {ok, DownstreamOp} = downstream({update, {{key1, register_lww}, {assign, <<"test">>}}}, Map1), - ?assertMatch({update, {{key1, register_lww}, {_TS, <<"test">>}}}, DownstreamOp), + {ok, DownstreamOp} = downstream({update, {{key1, antidote_crdt_register_lww}, {assign, <<"test">>}}}, Map1), + ?assertMatch({update, {{key1, antidote_crdt_register_lww}, {_TS, <<"test">>}}}, DownstreamOp), {ok, Map2} = update(DownstreamOp, Map1), - ?assertEqual([{{key1, register_lww}, <<"test">>}], value(Map2)). + ?assertEqual([{{key1, antidote_crdt_register_lww}, <<"test">>}], value(Map2)). update2_test() -> Map1 = new(), - {ok, Effect1} = downstream({update, [{{a, set_aw}, {add, a}}]}, Map1), + {ok, Effect1} = downstream({update, [{{a, antidote_crdt_set_aw}, {add, a}}]}, Map1), {ok, Map2} = update(Effect1, Map1), - ?assertEqual([{{a, set_aw}, [a]}], value(Map2)). + ?assertEqual([{{a, antidote_crdt_set_aw}, [a]}], value(Map2)). -endif. diff --git a/src/map_rr.erl b/src/antidote_crdt_map_rr.erl similarity index 87% rename from src/map_rr.erl rename to src/antidote_crdt_map_rr.erl index 2d80525..4f39b41 100644 --- a/src/map_rr.erl +++ b/src/antidote_crdt_map_rr.erl @@ -18,7 +18,7 @@ %% %% ------------------------------------------------------------------- -%% @doc module map_rr - A CRDT map datatype with a reset functionality +%% @doc module antidote_crdt_map_rr - A CRDT map datatype with a reset functionality %% %% Inserting a new element in the map: %% if element already there -> do nothing @@ -45,7 +45,7 @@ %% Resetting the map means removing all the current entries %% --module(map_rr). +-module(antidote_crdt_map_rr). -behaviour(antidote_crdt). @@ -241,13 +241,13 @@ is_bottom(Map) -> reset1_test() -> Map0 = new(), % DC1: a.incr - {ok, Incr1} = downstream({update, {{a, counter_fat}, {increment, 1}}}, Map0), + {ok, Incr1} = downstream({update, {{a, antidote_crdt_counter_fat}, {increment, 1}}}, Map0), {ok, Map1a} = update(Incr1, Map0), % DC1 reset {ok, Reset1} = downstream({reset, {}}, Map1a), {ok, Map1b} = update(Reset1, Map1a), % DC2 a.remove - {ok, Remove1} = downstream({remove, {a, counter_fat}}, Map0), + {ok, Remove1} = downstream({remove, {a, antidote_crdt_counter_fat}}, Map0), {ok, Map2a} = update(Remove1, Map0), % DC2 --> DC1 {ok, Map1c} = update(Remove1, Map1b), @@ -255,7 +255,7 @@ reset1_test() -> {ok, Reset2} = downstream({reset, {}}, Map1c), {ok, Map1d} = update(Reset2, Map1c), % DC1: a.incr - {ok, Incr2} = downstream({update, {{a, counter_fat}, {increment, 2}}}, Map1d), + {ok, Incr2} = downstream({update, {{a, antidote_crdt_counter_fat}, {increment, 2}}}, Map1d), {ok, Map1e} = update(Incr2, Map1d), io:format("Map0 = ~p~n", [Map0]), @@ -272,24 +272,24 @@ reset1_test() -> io:format("Map1e = ~p~n", [Map1e]), ?assertEqual([], value(Map0)), - ?assertEqual([{{a, counter_fat}, 1}], value(Map1a)), + ?assertEqual([{{a, antidote_crdt_counter_fat}, 1}], value(Map1a)), ?assertEqual([], value(Map1b)), ?assertEqual([], value(Map2a)), ?assertEqual([], value(Map1c)), ?assertEqual([], value(Map1d)), - ?assertEqual([{{a, counter_fat}, 2}], value(Map1e)). + ?assertEqual([{{a, antidote_crdt_counter_fat}, 2}], value(Map1e)). reset2_test() -> Map0 = new(), % DC1: s.add - {ok, Add1} = downstream({update, {{s, set_rw}, {add, a}}}, Map0), + {ok, Add1} = downstream({update, {{s, antidote_crdt_set_rw}, {add, a}}}, Map0), {ok, Map1a} = update(Add1, Map0), % DC1 reset {ok, Reset1} = downstream({reset, {}}, Map1a), {ok, Map1b} = update(Reset1, Map1a), % DC2 s.remove - {ok, Remove1} = downstream({remove, {s, set_rw}}, Map0), + {ok, Remove1} = downstream({remove, {s, antidote_crdt_set_rw}}, Map0), {ok, Map2a} = update(Remove1, Map0), % DC2 --> DC1 {ok, Map1c} = update(Remove1, Map1b), @@ -297,7 +297,7 @@ reset2_test() -> {ok, Reset2} = downstream({reset, {}}, Map1c), {ok, Map1d} = update(Reset2, Map1c), % DC1: s.add - {ok, Add2} = downstream({update, {{s, set_rw}, {add, b}}}, Map1d), + {ok, Add2} = downstream({update, {{s, antidote_crdt_set_rw}, {add, b}}}, Map1d), {ok, Map1e} = update(Add2, Map1d), io:format("Map0 = ~p~n" , [value(Map0)]), @@ -314,21 +314,21 @@ reset2_test() -> io:format("Map1e = ~p~n" , [value(Map1e)]), ?assertEqual([], value(Map0)), - ?assertEqual([{{s, set_rw}, [a]}], value(Map1a)), + ?assertEqual([{{s, antidote_crdt_set_rw}, [a]}], value(Map1a)), ?assertEqual([], value(Map1b)), ?assertEqual([], value(Map2a)), ?assertEqual([], value(Map1c)), ?assertEqual([], value(Map1d)), - ?assertEqual([{{s, set_rw}, [b]}], value(Map1e)). + ?assertEqual([{{s, antidote_crdt_set_rw}, [b]}], value(Map1e)). prop1_test() -> Map0 = new(), % DC1: s.add - {ok, Add1} = downstream({update, {{a, map_rr}, {update, {{a, set_rw}, {add, a}}}}}, Map0), + {ok, Add1} = downstream({update, {{a, antidote_crdt_map_rr}, {update, {{a, antidote_crdt_set_rw}, {add, a}}}}}, Map0), {ok, Map1a} = update(Add1, Map0), % DC1 reset - {ok, Reset1} = downstream({remove, {a, map_rr}}, Map1a), + {ok, Reset1} = downstream({remove, {a, antidote_crdt_map_rr}}, Map1a), {ok, Map1b} = update(Reset1, Map1a), io:format("Map0 = ~p~n", [Map0]), @@ -338,17 +338,17 @@ prop1_test() -> io:format("Map1b = ~p~n", [Map1b]), ?assertEqual([], value(Map0)), - ?assertEqual([{{a, map_rr}, [{{a, set_rw}, [a]}]}], value(Map1a)), + ?assertEqual([{{a, antidote_crdt_map_rr}, [{{a, antidote_crdt_set_rw}, [a]}]}], value(Map1a)), ?assertEqual([], value(Map1b)). prop2_test() -> Map0 = new(), % DC1: update remove - {ok, Add1} = downstream({update, [{{b, map_rr}, {remove, {a, set_rw}}}]}, Map0), + {ok, Add1} = downstream({update, [{{b, antidote_crdt_map_rr}, {remove, {a, antidote_crdt_set_rw}}}]}, Map0), {ok, Map1a} = update(Add1, Map0), % DC2 remove - {ok, Remove2} = downstream({remove, {b, map_rr}}, Map0), + {ok, Remove2} = downstream({remove, {b, antidote_crdt_map_rr}}, Map0), {ok, Map2a} = update(Remove2, Map0), % pull DC2 -> DC1 @@ -375,14 +375,14 @@ remove_test() -> ?assertEqual([], value(M1)), ?assertEqual(true, is_bottom(M1)), M2 = upd({update, [ - {{<<"a">>, set_aw}, {add, <<"1">>}}, - {{<<"b">>, register_mv}, {assign, <<"2">>}}, - {{<<"c">>, counter_fat}, {increment, 1}} + {{<<"a">>, antidote_crdt_set_aw}, {add, <<"1">>}}, + {{<<"b">>, antidote_crdt_register_mv}, {assign, <<"2">>}}, + {{<<"c">>, antidote_crdt_counter_fat}, {increment, 1}} ]}, M1), ?assertEqual([ - {{<<"a">>, set_aw}, [<<"1">>]}, - {{<<"b">>, register_mv}, [<<"2">>]}, - {{<<"c">>, counter_fat}, 1} + {{<<"a">>, antidote_crdt_set_aw}, [<<"1">>]}, + {{<<"b">>, antidote_crdt_register_mv}, [<<"2">>]}, + {{<<"c">>, antidote_crdt_counter_fat}, 1} ], value(M2)), ?assertEqual(false, is_bottom(M2)), M3 = upd({reset, {}}, M2), diff --git a/src/register_lww.erl b/src/antidote_crdt_register_lww.erl similarity index 83% rename from src/register_lww.erl rename to src/antidote_crdt_register_lww.erl index 67e2a5f..9f8083a 100644 --- a/src/register_lww.erl +++ b/src/antidote_crdt_register_lww.erl @@ -18,13 +18,13 @@ %% %% ------------------------------------------------------------------- -%% @doc module register_lww - An operation based last-writer-wins register +%% @doc module antidote_crdt_register_lww - An operation based last-writer-wins register %% Each operation is assigned a timestamp, which is guaranteed to be greater than %% the current timestamp. %% The current value of the register is the value assigned with the greatest timestamp %% or the empty binary if there was no assignment yet. --module(register_lww). +-module(antidote_crdt_register_lww). -behaviour(antidote_crdt). @@ -43,11 +43,11 @@ require_state_downstream/1 ]). --export_type([register_lww/0, register_lww_op/0]). +-export_type([antidote_crdt_register_lww/0, antidote_crdt_register_lww_op/0]). --opaque register_lww() :: {non_neg_integer(), term()}. +-opaque antidote_crdt_register_lww() :: {non_neg_integer(), term()}. --type register_lww_op() :: {assign, term(), non_neg_integer()} | {assign, term()}. +-type antidote_crdt_register_lww_op() :: {assign, term(), non_neg_integer()} | {assign, term()}. new() -> {0, <<>>}. @@ -55,7 +55,7 @@ new() -> value({_Time, Val}) -> Val. --spec downstream(register_lww_op(), register_lww()) -> {ok, term()}. +-spec downstream(antidote_crdt_register_lww_op(), antidote_crdt_register_lww()) -> {ok, term()}. downstream({assign, Value, Time}, {OldTime, _OldValue}) -> {ok, {max(Time, OldTime + 1), Value}}; downstream({assign, Value}, State) -> diff --git a/src/register_mv.erl b/src/antidote_crdt_register_mv.erl similarity index 77% rename from src/register_mv.erl rename to src/antidote_crdt_register_mv.erl index 774d2db..007d5b8 100644 --- a/src/register_mv.erl +++ b/src/antidote_crdt_register_mv.erl @@ -1,6 +1,6 @@ %% ------------------------------------------------------------------- %% -%% riak_dt_register_mv: A DVVSet based multi value register +%% riak_dt_antidote_crdt_register_mv: A DVVSet based multi value register %% %% Copyright (c) 2007-2013 Basho Technologies, Inc. All Rights Reserved. %% @@ -31,7 +31,7 @@ %% %% @end --module(register_mv). +-module(antidote_crdt_register_mv). -behaviour(antidote_crdt). @@ -53,34 +53,34 @@ -include_lib("eunit/include/eunit.hrl"). -endif. --export_type([register_mv/0, register_mv_op/0]). +-export_type([antidote_crdt_register_mv/0, antidote_crdt_register_mv_op/0]). %% TODO: make opaque --type register_mv() :: [{term(), uniqueToken()}]. +-type antidote_crdt_register_mv() :: [{term(), uniqueToken()}]. -type uniqueToken() :: term(). --type register_mv_effect() :: +-type antidote_crdt_register_mv_effect() :: {Value::term(), uniqueToken(), Overridden::[uniqueToken()]} | {reset, Overridden::[uniqueToken()]}. --type register_mv_op() :: {assign, term()}. +-type antidote_crdt_register_mv_op() :: {assign, term()}. -%% @doc Create a new, empty `register_mv()' --spec new() -> register_mv(). +%% @doc Create a new, empty `antidote_crdt_register_mv()' +-spec new() -> antidote_crdt_register_mv(). new() -> []. -%% @doc The values of this `register_mv()'. Multiple values can be returned, +%% @doc The values of this `antidote_crdt_register_mv()'. Multiple values can be returned, %% since there can be diverged value in this register. --spec value(register_mv()) -> [term()]. +-spec value(antidote_crdt_register_mv()) -> [term()]. value(MVReg) -> [V || {V, _} <- MVReg]. --spec downstream(register_mv_op(), register_mv()) -> {ok, register_mv_effect()}. +-spec downstream(antidote_crdt_register_mv_op(), antidote_crdt_register_mv()) -> {ok, antidote_crdt_register_mv_effect()}. downstream({assign, Value}, MVReg) -> Token = unique(), Overridden = [Tok || {_, Tok} <- MVReg], @@ -94,7 +94,7 @@ unique() -> crypto:strong_rand_bytes(20). --spec update(register_mv_effect(), register_mv()) -> {ok, register_mv()}. +-spec update(antidote_crdt_register_mv_effect(), antidote_crdt_register_mv()) -> {ok, antidote_crdt_register_mv()}. update({Value, Token, Overridden}, MVreg) -> % remove overridden values MVreg2 = [{V, T} || {V, T} <- MVreg, not lists:member(T, Overridden)], @@ -110,19 +110,19 @@ insert_sorted(A, [X|Xs]) when A < X -> [A, X|Xs]; insert_sorted(A, [X|Xs]) -> [X|insert_sorted(A, Xs)]. --spec equal(register_mv(), register_mv()) -> boolean(). +-spec equal(antidote_crdt_register_mv(), antidote_crdt_register_mv()) -> boolean(). equal(MVReg1, MVReg2) -> MVReg1 == MVReg2. -define(TAG, 85). -define(V1_VERS, 1). --spec to_binary(register_mv()) -> binary(). +-spec to_binary(antidote_crdt_register_mv()) -> binary(). to_binary(MVReg) -> <>. -%% @doc Decode binary `register_mv()' --spec from_binary(binary()) -> {ok, register_mv()} | {error, term()}. +%% @doc Decode binary `antidote_crdt_register_mv()' +-spec from_binary(binary()) -> {ok, antidote_crdt_register_mv()} | {error, term()}. from_binary(<>) -> {ok, riak_dt:from_binary(Bin)}. diff --git a/src/set_aw.erl b/src/antidote_crdt_set_aw.erl similarity index 90% rename from src/set_aw.erl rename to src/antidote_crdt_set_aw.erl index 884619b..4e7b974 100644 --- a/src/set_aw.erl +++ b/src/antidote_crdt_set_aw.erl @@ -1,6 +1,6 @@ %% ------------------------------------------------------------------- %% -%% crdt_set_aw: A convergent, replicated, operation based observe remove set +%% crdt_antidote_crdt_set_aw: A convergent, replicated, operation based observe remove set %% %% Copyright (c) 2007-2012 Basho Technologies, Inc. All Rights Reserved. %% @@ -31,7 +31,7 @@ %% remove_all that removes a list of elements from the set; update, that contains %% a list of previous four commands. %% -%% This file is adapted from riak_dt_set_aw, a state-based implementation of +%% This file is adapted from riak_dt_antidote_crdt_set_aw, a state-based implementation of %% Observed-Remove Set. %% The changes are as follows: %% 1. `generate_downstream/3' is added, as this is necessary for op-based CRDTs. @@ -42,7 +42,7 @@ %% Convergent and Commutative Replicated Data Types. http://hal.upmc.fr/inria-00555588/ %% %% @end --module(set_aw). +-module(antidote_crdt_set_aw). -include("antidote_crdt.hrl"). @@ -65,12 +65,12 @@ -include_lib("eunit/include/eunit.hrl"). -endif. --export_type([set_aw/0, binary_set_aw/0, set_aw_op/0]). --opaque set_aw() :: orddict:orddict(member(), tokens()). +-export_type([antidote_crdt_set_aw/0, binary_antidote_crdt_set_aw/0, antidote_crdt_set_aw_op/0]). +-opaque antidote_crdt_set_aw() :: orddict:orddict(member(), tokens()). --type binary_set_aw() :: binary(). %% A binary that from_binary/1 will operate on. +-type binary_antidote_crdt_set_aw() :: binary(). %% A binary that from_binary/1 will operate on. --type set_aw_op() :: +-type antidote_crdt_set_aw_op() :: {add, member()} | {remove, member()} | {add_all, [member()]} @@ -88,12 +88,12 @@ -type token() :: binary(). -type tokens() :: [token()]. --spec new() -> set_aw(). +-spec new() -> antidote_crdt_set_aw(). new() -> orddict:new(). -%% @doc return all existing elements in the `set_aw()'. --spec value(set_aw()) -> [member()]. +%% @doc return all existing elements in the `antidote_crdt_set_aw()'. +-spec value(antidote_crdt_set_aw()) -> [member()]. value(Set_aw) -> orddict:fetch_keys(Set_aw). @@ -101,8 +101,8 @@ value(Set_aw) -> %% If the operation is add or add_all, generate unique tokens for %% each element and fetches the current supporting tokens. %% If the operation is remove or remove_all, fetches current -%% supporting tokens of these elements existing in the `set_aw()'. --spec downstream(set_aw_op(), set_aw()) -> {ok, downstream_op()}. +%% supporting tokens of these elements existing in the `antidote_crdt_set_aw()'. +-spec downstream(antidote_crdt_set_aw_op(), antidote_crdt_set_aw()) -> {ok, downstream_op()}. downstream({add, Elem}, Set_aw) -> downstream({add_all, [Elem]}, Set_aw); downstream({add_all, Elems}, Set_aw) -> @@ -124,12 +124,12 @@ downstream({reset, {}}, Set_aw) -> % reset is like removing all elements downstream({remove_all, value(Set_aw)}, Set_aw). -%% @doc apply downstream operations and update an `set_aw()'. --spec update(downstream_op(), set_aw()) -> {ok, set_aw()}. +%% @doc apply downstream operations and update an `antidote_crdt_set_aw()'. +-spec update(downstream_op(), antidote_crdt_set_aw()) -> {ok, antidote_crdt_set_aw()}. update(DownstreamOp, Set_aw) -> {ok, apply_downstreams(DownstreamOp, Set_aw)}. --spec equal(set_aw(), set_aw()) -> boolean(). +-spec equal(antidote_crdt_set_aw(), antidote_crdt_set_aw()) -> boolean(). equal(Set_awA, Set_awB) -> % Everything inside is ordered, so this should work Set_awA == Set_awB. @@ -138,7 +138,7 @@ equal(Set_awA, Set_awB) -> -define(TAG, ?DT_ORSET_TAG). -define(V1_VERS, 1). --spec to_binary(set_aw()) -> binary_set_aw(). +-spec to_binary(antidote_crdt_set_aw()) -> binary_antidote_crdt_set_aw(). to_binary(Set_aw) -> %% @TODO something smarter <>. @@ -176,7 +176,7 @@ create_downstreams(CreateDownstream, [Elem1|ElemsRest]=Elems, [{Elem2, Tokens}|S create_downstreams(CreateDownstream, ElemsRest, Set_aw, [DownstreamOp|DownstreamOps]) end. -%% @private apply a list of downstream ops to a given set_aw +%% @private apply a list of downstream ops to a given antidote_crdt_set_aw apply_downstreams([], Set_aw) -> Set_aw; apply_downstreams(Ops, []) -> diff --git a/src/set_go.erl b/src/antidote_crdt_set_go.erl similarity index 80% rename from src/set_go.erl rename to src/antidote_crdt_set_go.erl index 455e80b..9707f54 100644 --- a/src/set_go.erl +++ b/src/antidote_crdt_set_go.erl @@ -18,9 +18,9 @@ %% %% ------------------------------------------------------------------- -%% @doc module set_go - An operation based grow-only set +%% @doc module antidote_crdt_set_go - An operation based grow-only set --module(set_go). +-module(antidote_crdt_set_go). -behaviour(antidote_crdt). @@ -39,11 +39,11 @@ require_state_downstream/1 ]). --type set_go() :: ordsets:ordset(member()). --type set_go_op() :: {add, member()} +-type antidote_crdt_set_go() :: ordsets:ordset(member()). +-type antidote_crdt_set_go_op() :: {add, member()} | {add_all, [member()]}. --type set_go_effect() :: set_go(). +-type antidote_crdt_set_go_effect() :: antidote_crdt_set_go(). -type member() :: term(). new() -> @@ -52,7 +52,7 @@ new() -> value(Set) -> Set. --spec downstream(set_go_op(), set_go()) -> {ok, set_go_effect()}. +-spec downstream(antidote_crdt_set_go_op(), antidote_crdt_set_go()) -> {ok, antidote_crdt_set_go_effect()}. downstream({add, Elem}, _State) -> {ok, ordsets:from_list([Elem])}; downstream({add_all, Elems}, _State) -> @@ -81,6 +81,6 @@ all_test() -> S0 = new(), {ok, Downstream} = downstream({add, a}, S0), {ok, S1} = update(Downstream, S0), - ?assertEqual(1, riak_dt_set_go:stat(element_count, S1)). + ?assertEqual(1, riak_dt_antidote_crdt_set_go:stat(element_count, S1)). -endif. diff --git a/src/set_rw.erl b/src/antidote_crdt_set_rw.erl similarity index 94% rename from src/set_rw.erl rename to src/antidote_crdt_set_rw.erl index ff0df73..c7882e4 100644 --- a/src/set_rw.erl +++ b/src/antidote_crdt_set_rw.erl @@ -42,7 +42,7 @@ %% (i.e. AddTokens == [] and RemoveTokens == []) %% @end --module(set_rw). +-module(antidote_crdt_set_rw). %% Callbacks @@ -65,12 +65,12 @@ -include_lib("eunit/include/eunit.hrl"). -endif. --export_type([set_rw/0, binary_set_rw/0, set_rw_op/0]). --opaque set_rw() :: orddict:orddict(term(), {tokens(), tokens()}). +-export_type([antidote_crdt_set_rw/0, binary_antidote_crdt_set_rw/0, antidote_crdt_set_rw_op/0]). +-opaque antidote_crdt_set_rw() :: orddict:orddict(term(), {tokens(), tokens()}). --type binary_set_rw() :: binary(). %% A binary that from_binary/1 will operate on. +-type binary_antidote_crdt_set_rw() :: binary(). %% A binary that from_binary/1 will operate on. --type set_rw_op() :: +-type antidote_crdt_set_rw_op() :: {add, member()} | {remove, member()} | {add_all, [member()]} @@ -84,15 +84,15 @@ -type token() :: term(). -type tokens() :: [token()]. --spec new() -> set_rw(). +-spec new() -> antidote_crdt_set_rw(). new() -> orddict:new(). --spec value(set_rw()) -> [member()]. +-spec value(antidote_crdt_set_rw()) -> [member()]. value(RWSet) -> [Elem || {Elem, {_, []}} <- RWSet]. --spec downstream(set_rw_op(), set_rw()) -> {ok, downstream_op()}. +-spec downstream(antidote_crdt_set_rw_op(), antidote_crdt_set_rw()) -> {ok, downstream_op()}. downstream({add, Elem}, RWSet) -> downstream({add_all, [Elem]}, RWSet); downstream({add_all, Elems}, RWSet) -> @@ -146,7 +146,7 @@ create_downstreams(CreateDownstream, [Elem1|ElemsRest]=Elems, [{Elem2, {AddToken unique() -> crypto:strong_rand_bytes(20). --spec update(downstream_op(), set_rw()) -> {ok, set_rw()}. +-spec update(downstream_op(), antidote_crdt_set_rw()) -> {ok, antidote_crdt_set_rw()}. update(DownstreamOp, RWSet) -> RWSet1 = apply_downstreams(DownstreamOp, RWSet), RWSet2 = [Entry || {_, {AddTokens, RemoveTokens}} = Entry <- RWSet1, AddTokens =/= [] orelse RemoveTokens =/= []], @@ -175,14 +175,14 @@ apply_downstream(Elem, SeenTokens, ToAdd, ToRemove, CurrentAddTokens, CurrentRem --spec equal(set_rw(), set_rw()) -> boolean(). +-spec equal(antidote_crdt_set_rw(), antidote_crdt_set_rw()) -> boolean(). equal(ORDictA, ORDictB) -> ORDictA == ORDictB. % Everything inside is ordered, so this should work -define(TAG, 77). -define(V1_VERS, 1). --spec to_binary(set_rw()) -> binary_set_rw(). +-spec to_binary(antidote_crdt_set_rw()) -> binary_antidote_crdt_set_rw(). to_binary(Set) -> %% @TODO something smarter <>. diff --git a/test/prop_counter_fat.erl b/test/prop_counter_fat.erl index 7f328ec..f343dcc 100644 --- a/test/prop_counter_fat.erl +++ b/test/prop_counter_fat.erl @@ -28,7 +28,7 @@ prop_counter_fat_spec() -> - crdt_properties:crdt_satisfies_spec(counter_fat, fun op/0, fun spec/1). + crdt_properties:crdt_satisfies_spec(antidote_crdt_counter_fat, fun op/0, fun spec/1). spec(Operations1) -> diff --git a/test/prop_counter_pn.erl b/test/prop_counter_pn.erl index 7a2d7a7..75cdd87 100644 --- a/test/prop_counter_pn.erl +++ b/test/prop_counter_pn.erl @@ -28,7 +28,7 @@ prop_counter_pn_spec() -> - crdt_properties:crdt_satisfies_spec(counter_pn, fun op/0, fun spec/1). + crdt_properties:crdt_satisfies_spec(antidote_crdt_counter_pn, fun op/0, fun spec/1). spec(Operations) -> diff --git a/test/prop_flag_dw.erl b/test/prop_flag_dw.erl index d3de5a0..13b544c 100644 --- a/test/prop_flag_dw.erl +++ b/test/prop_flag_dw.erl @@ -27,7 +27,7 @@ -export([prop_flag_dw_spec/0, op/0, spec/1]). prop_flag_dw_spec() -> - crdt_properties:crdt_satisfies_spec(flag_dw, fun op/0, fun spec/1). + crdt_properties:crdt_satisfies_spec(antidote_crdt_flag_dw, fun op/0, fun spec/1). spec(Operations) -> diff --git a/test/prop_flag_ew.erl b/test/prop_flag_ew.erl index 6e59a1b..a786d80 100644 --- a/test/prop_flag_ew.erl +++ b/test/prop_flag_ew.erl @@ -27,7 +27,7 @@ -export([prop_flag_ew_spec/0, op/0, spec/1]). prop_flag_ew_spec() -> - crdt_properties:crdt_satisfies_spec(flag_ew, fun op/0, fun spec/1). + crdt_properties:crdt_satisfies_spec(antidote_crdt_flag_ew, fun op/0, fun spec/1). spec(Operations) -> diff --git a/test/prop_map_go.erl b/test/prop_map_go.erl index 77b9d65..e29b2f9 100644 --- a/test/prop_map_go.erl +++ b/test/prop_map_go.erl @@ -28,7 +28,7 @@ prop_map_go_spec() -> - crdt_properties:crdt_satisfies_spec(map_go, fun op/0, fun spec/1). + crdt_properties:crdt_satisfies_spec(antidote_crdt_map_go, fun op/0, fun spec/1). spec(Operations1) -> @@ -41,9 +41,9 @@ spec(Operations1) -> nestedOps(Operations, Key) -> [{Clock, NestedOp} || {Clock, {update, {Key2, NestedOp}}} <- Operations, Key == Key2]. -nestedSpec(map_go, Ops) -> spec(Ops); -nestedSpec(set_aw, Ops) -> prop_set_aw:spec(Ops); -nestedSpec(counter_pn, Ops) -> prop_counter_pn:spec(Ops). +nestedSpec(antidote_crdt_map_go, Ops) -> spec(Ops); +nestedSpec(antidote_crdt_set_aw, Ops) -> prop_set_aw:spec(Ops); +nestedSpec(antidote_crdt_counter_pn, Ops) -> prop_counter_pn:spec(Ops). normalizeOp({Clock, {update, List}}) when is_list(List) -> @@ -71,13 +71,13 @@ nestedOp(Size) -> [ % TODO add other type (orset) and recursive maps % TODO make sure that keys are unique here and in the is_operation check - {{key(), set_aw}, prop_set_aw:op()}, - {{key(), counter_pn}, prop_counter_pn:op()} + {{key(), antidote_crdt_set_aw}, prop_set_aw:op()}, + {{key(), antidote_crdt_counter_pn}, prop_counter_pn:op()} ] ++ if Size > 1 -> - [{{key(), map_go}, ?LAZY(op(Size div 2))}]; + [{{key(), antidote_crdt_map_go}, ?LAZY(op(Size div 2))}]; true -> [] end ). diff --git a/test/prop_map_rr.erl b/test/prop_map_rr.erl index bd069de..290c9c4 100644 --- a/test/prop_map_rr.erl +++ b/test/prop_map_rr.erl @@ -27,7 +27,7 @@ -export([prop_map_rr_spec/0]). prop_map_rr_spec() -> - crdt_properties:crdt_satisfies_partial_spec(map_rr, fun op/0, fun spec/2). + crdt_properties:crdt_satisfies_partial_spec(antidote_crdt_map_rr, fun op/0, fun spec/2). spec(Operations1, Value) -> @@ -43,7 +43,7 @@ spec(Operations1, Value) -> io:format("Operations = ~p~n", [Operations]), io:format("GroupedByKey = ~p~n", [GroupedByKey]) end, - nestedSpec(Type, Ops, map_rr:get({Key,Type}, Value)) + nestedSpec(Type, Ops, antidote_crdt_map_rr:get({Key,Type}, Value)) ) end, conjunction( @@ -65,10 +65,10 @@ nestedOps(Operations, {_,Type}=Key) -> end, Resets ++ [{Clock, NestedOp} || {Clock, {update, {Key2, NestedOp}}} <- Operations, Key == Key2]. -nestedSpec(map_rr, Ops, Value) -> spec(Ops, Value); -% nestedSpec(set_aw, Ops) -> prop_set_aw:spec(Ops); -% nestedSpec(counter_fat, Ops) -> prop_counter_fat:spec(Ops); -nestedSpec(set_rw, Ops, Value) -> +nestedSpec(antidote_crdt_map_rr, Ops, Value) -> spec(Ops, Value); +% nestedSpec(antidote_crdt_set_aw, Ops) -> prop_set_aw:spec(Ops); +% nestedSpec(antidote_crdt_counter_fat, Ops) -> prop_counter_fat:spec(Ops); +nestedSpec(antidote_crdt_set_rw, Ops, Value) -> (crdt_properties:spec_to_partial(fun prop_set_rw:spec/1))(Ops, Value). % normalizes operations (update-lists into single update-operations) @@ -114,14 +114,14 @@ removeDuplicateKeys([{Key,Op}|Rest], Keys) -> nestedOp(Size) -> oneof( [ - % {{key(), counter_fat}, prop_counter_fat:op()}, - % {{key(), set_aw}, prop_set_aw:op()}, - {{key(), set_rw}, prop_set_rw:op()} + % {{key(), antidote_crdt_counter_fat}, prop_counter_fat:op()}, + % {{key(), antidote_crdt_set_aw}, prop_set_aw:op()}, + {{key(), antidote_crdt_set_rw}, prop_set_rw:op()} ] ++ if Size > 1 -> - [{{key(), map_rr}, ?LAZY(op(Size div 2))}]; + [{{key(), antidote_crdt_map_rr}, ?LAZY(op(Size div 2))}]; true -> [] end ). @@ -129,7 +129,7 @@ nestedOp(Size) -> typed_key() -> {key(), crdt_type()}. crdt_type() -> - oneof([set_rw, map_rr]). + oneof([antidote_crdt_set_rw, antidote_crdt_map_rr]). key() -> oneof([key1,key2,key3,key4]). diff --git a/test/prop_register_lww.erl b/test/prop_register_lww.erl index e1d9735..904e3c2 100644 --- a/test/prop_register_lww.erl +++ b/test/prop_register_lww.erl @@ -28,7 +28,7 @@ prop_register_lww_spec() -> - crdt_properties:crdt_satisfies_spec(register_lww, fun op/0, fun spec/1). + crdt_properties:crdt_satisfies_spec(antidote_crdt_register_lww, fun op/0, fun spec/1). spec(Operations) -> diff --git a/test/prop_register_mv.erl b/test/prop_register_mv.erl index 16b6fad..4aba5e8 100644 --- a/test/prop_register_mv.erl +++ b/test/prop_register_mv.erl @@ -28,7 +28,7 @@ prop_register_mv_spec() -> - crdt_properties:crdt_satisfies_spec(register_mv, fun op/0, fun spec/1). + crdt_properties:crdt_satisfies_spec(antidote_crdt_register_mv, fun op/0, fun spec/1). spec(Operations) -> diff --git a/test/prop_set_aw.erl b/test/prop_set_aw.erl index 5c0ee7a..dcc16eb 100644 --- a/test/prop_set_aw.erl +++ b/test/prop_set_aw.erl @@ -28,7 +28,7 @@ prop_set_aw_spec() -> - crdt_properties:crdt_satisfies_spec(set_aw, fun op/0, fun spec/1). + crdt_properties:crdt_satisfies_spec(antidote_crdt_set_aw, fun op/0, fun spec/1). spec(Operations1) -> diff --git a/test/prop_set_go.erl b/test/prop_set_go.erl index 718a63e..a1c110f 100644 --- a/test/prop_set_go.erl +++ b/test/prop_set_go.erl @@ -28,7 +28,7 @@ prop_set_go_spec() -> - crdt_properties:crdt_satisfies_spec(set_go, fun op/0, fun spec/1). + crdt_properties:crdt_satisfies_spec(antidote_crdt_set_go, fun op/0, fun spec/1). spec(Operations) -> diff --git a/test/prop_set_rw.erl b/test/prop_set_rw.erl index cc67da5..dc3ea1c 100644 --- a/test/prop_set_rw.erl +++ b/test/prop_set_rw.erl @@ -28,7 +28,7 @@ prop_set_rw_spec() -> - crdt_properties:crdt_satisfies_spec(set_rw, fun op/0, fun spec/1). + crdt_properties:crdt_satisfies_spec(antidote_crdt_set_rw, fun op/0, fun spec/1). spec(Operations1) -> From a2fe3d5fb0316a4f59d2de4f767060fa0aadc0c8 Mon Sep 17 00:00:00 2001 From: Georges Younes Date: Mon, 5 Feb 2018 10:58:11 +0000 Subject: [PATCH 5/6] update .gitignore --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 1c908bd..5200b23 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,4 @@ TEST-file_"antidote_crdt.app".xml *.swp src/*.swp test/*.swp -*.beam -TEST-file_antidote_crdt.app.xml \ No newline at end of file +*.beam \ No newline at end of file From 303dc709bd9e38e2752022c4bc9e4f3cffacbed2 Mon Sep 17 00:00:00 2001 From: Georges Younes Date: Mon, 5 Feb 2018 17:01:28 +0000 Subject: [PATCH 6/6] keep type names short --- src/antidote_crdt_flag_dw.erl | 16 ++++++++-------- src/antidote_crdt_flag_ew.erl | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/antidote_crdt_flag_dw.erl b/src/antidote_crdt_flag_dw.erl index c052e21..4fdaf4a 100644 --- a/src/antidote_crdt_flag_dw.erl +++ b/src/antidote_crdt_flag_dw.erl @@ -46,21 +46,21 @@ -define(TAG, 77). -define(V1_VERS, 1). --export_type([antidote_crdt_flag_dw/0]). --opaque antidote_crdt_flag_dw() :: {antidote_crdt_flag_helper:tokens(), antidote_crdt_flag_helper:tokens()}. +-export_type([flag_dw/0]). +-opaque flag_dw() :: {antidote_crdt_flag_helper:tokens(), antidote_crdt_flag_helper:tokens()}. %% SeenTokens, NewEnableTokens, NewDisableTokens -type downstream_op() :: {antidote_crdt_flag_helper:tokens(), antidote_crdt_flag_helper:tokens(), antidote_crdt_flag_helper:tokens()}. --spec new() -> antidote_crdt_flag_dw(). +-spec new() -> flag_dw(). new() -> {[], []}. --spec value(antidote_crdt_flag_dw()) -> boolean(). +-spec value(flag_dw()) -> boolean(). value({EnableTokens, DisableTokens}) -> DisableTokens == [] andalso EnableTokens =/= []. --spec downstream(antidote_crdt_flag_helper:op(), antidote_crdt_flag_dw()) -> {ok, downstream_op()}. +-spec downstream(antidote_crdt_flag_helper:op(), flag_dw()) -> {ok, downstream_op()}. downstream({disable, {}}, {EnableTokens, DisableTokens}) -> {ok, {EnableTokens ++ DisableTokens, [], [antidote_crdt_flag_helper:unique()]}}; downstream({enable, {}}, {EnableTokens, DisableTokens}) -> @@ -68,17 +68,17 @@ downstream({enable, {}}, {EnableTokens, DisableTokens}) -> downstream({reset, {}}, {EnableTokens, DisableTokens}) -> {ok, {EnableTokens ++ DisableTokens, [], []}}. --spec update(downstream_op(), antidote_crdt_flag_dw()) -> {ok, antidote_crdt_flag_dw()}. +-spec update(downstream_op(), flag_dw()) -> {ok, flag_dw()}. update({SeenTokens, NewEnableTokens, NewDisableTokens}, {CurrentEnableTokens, CurrentDisableTokens}) -> FinalEnableTokens = (CurrentEnableTokens ++ NewEnableTokens) -- SeenTokens, FinalDisableTokens = (CurrentDisableTokens ++ NewDisableTokens) -- SeenTokens, {ok, {FinalEnableTokens, FinalDisableTokens}}. --spec equal(antidote_crdt_flag_dw(), antidote_crdt_flag_dw()) -> boolean(). +-spec equal(flag_dw(), flag_dw()) -> boolean(). equal(Flag1, Flag2) -> Flag1 == Flag2. --spec to_binary(antidote_crdt_flag_dw()) -> antidote_crdt_flag_helper:binary_flag(). +-spec to_binary(flag_dw()) -> antidote_crdt_flag_helper:binary_flag(). to_binary(Flag) -> %% @TODO something smarter <>. diff --git a/src/antidote_crdt_flag_ew.erl b/src/antidote_crdt_flag_ew.erl index 37db0ba..c248bd0 100644 --- a/src/antidote_crdt_flag_ew.erl +++ b/src/antidote_crdt_flag_ew.erl @@ -46,21 +46,21 @@ -define(TAG, 77). -define(V1_VERS, 1). --export_type([antidote_crdt_flag_ew/0]). --opaque antidote_crdt_flag_ew() :: antidote_crdt_flag_helper:flag(). +-export_type([flag_ew/0]). +-opaque flag_ew() :: antidote_crdt_flag_helper:flag(). %% SeenTokens, NewTokens -type downstream_op() :: {antidote_crdt_flag_helper:tokens(), antidote_crdt_flag_helper:tokens()}. --spec new() -> antidote_crdt_flag_ew(). +-spec new() -> flag_ew(). new() -> []. --spec value(antidote_crdt_flag_ew()) -> boolean(). +-spec value(flag_ew()) -> boolean(). value(EnableTokens) -> EnableTokens =/= []. --spec downstream(antidote_crdt_flag_helper:op(), antidote_crdt_flag_ew()) -> {ok, downstream_op()}. +-spec downstream(antidote_crdt_flag_helper:op(), flag_ew()) -> {ok, downstream_op()}. downstream({disable, {}}, Tokens) -> {ok, {Tokens, []}}; downstream({enable, {}}, Tokens) -> @@ -68,16 +68,16 @@ downstream({enable, {}}, Tokens) -> downstream({reset, {}}, Tokens) -> {ok, {Tokens, []}}. --spec update(downstream_op(), antidote_crdt_flag_ew()) -> {ok, antidote_crdt_flag_ew()}. +-spec update(downstream_op(), flag_ew()) -> {ok, flag_ew()}. update({SeenTokens, NewTokens}, CurrentTokens) -> FinalTokens = (CurrentTokens ++ NewTokens) -- SeenTokens, {ok, FinalTokens}. --spec equal(antidote_crdt_flag_ew(), antidote_crdt_flag_ew()) -> boolean(). +-spec equal(flag_ew(), flag_ew()) -> boolean(). equal(Flag1, Flag2) -> Flag1 == Flag2. % Everything inside is ordered, so this should work --spec to_binary(antidote_crdt_flag_ew()) -> antidote_crdt_flag_helper:binary_flag(). +-spec to_binary(flag_ew()) -> antidote_crdt_flag_helper:binary_flag(). to_binary(Flag) -> %% @TODO something smarter <>.