Skip to content
This repository was archived by the owner on May 27, 2022. It is now read-only.

Commit 656a8c6

Browse files
authored
Merge pull request #21 from gyounes/master
Changes to antidote CRDTs (as per M12) - new module names - removed experimental CRDTs: integer, rga, map_aw - code cleanup
2 parents b41a44d + 303dc70 commit 656a8c6

32 files changed

+291
-1292
lines changed

include/antidote_crdt.hrl

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,8 @@
44
-type value() :: term().
55
-type reason() :: term().
66

7-
-type pncounter() :: integer().
8-
-type pncounter_update() :: {increment, integer()} |
9-
{decrement, integer()}.
10-
-type pncounter_effect() :: integer().
11-
-type pncounter_value() :: integer().
12-
13-
147
-export_type([ crdt/0,
158
update/0,
169
effect/0,
17-
value/0,
18-
pncounter/0,
19-
pncounter_update/0,
20-
pncounter_effect/0,
21-
pncounter_value/0
10+
value/0
2211
]).

src/antidote_crdt.erl

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,43 @@
1919
%% -------------------------------------------------------------------
2020

2121
%% antidote_crdt.erl : behaviour for op-based CRDTs
22+
%% Naming pattern of antidote crdts: <type>_<semantics>
23+
%% if there is only one kind of semantics implemented for a certain type
24+
%% only the type is used in the name e.g. rga
25+
%% counter_pn: PN-Counter aka Posistive Negative Counter
26+
%% counter_b: Bounded Counter
27+
%% counter_fat: Fat Counter
28+
%% integer: Integer (Experimental)
29+
%% flag_ew: Enable Wins Flag aka EW-Flag
30+
%% flag_dw: Disable Wins Flag DW-Flag
31+
%% set_go: Grow Only Set aka G-Set
32+
%% set_aw: Add Wins Set aka AW-Set, previously OR-Set (Observed Remove Set)
33+
%% set_rw: Remove Wins Set aka RW-Set
34+
%% register_lww: Last Writer Wins Register aka LWW-Reg
35+
%% register_mv: MultiValue Register aka MV-Reg
36+
%% map_go: Grow Only Map aka G-Map
37+
%% map_aw: Add Wins Map aka AW-Map (Experimental)
38+
%% map_rr: Recursive Resets Map akak RR-Map
39+
%% rga: Replicated Growable Array (Experimental)
40+
2241

2342

2443
-module(antidote_crdt).
2544

2645
-include("antidote_crdt.hrl").
2746

28-
-define(CRDTS, [antidote_crdt_counter,
29-
antidote_crdt_orset,
30-
antidote_crdt_gset,
31-
antidote_crdt_rga,
32-
antidote_crdt_bcounter,
33-
antidote_crdt_mvreg,
34-
antidote_crdt_map,
35-
antidote_crdt_lwwreg,
36-
antidote_crdt_gmap,
37-
antidote_crdt_set_rw,
38-
antidote_crdt_integer,
39-
antidote_crdt_map_aw,
40-
antidote_crdt_map_rr,
41-
antidote_crdt_fat_counter,
47+
-define(CRDTS, [antidote_crdt_counter_pn,
48+
antidote_crdt_counter_b,
49+
antidote_crdt_counter_fat,
4250
antidote_crdt_flag_ew,
43-
antidote_crdt_flag_dw
44-
]).
51+
antidote_crdt_flag_dw,
52+
antidote_crdt_set_go,
53+
antidote_crdt_set_aw,
54+
antidote_crdt_set_rw,
55+
antidote_crdt_register_lww,
56+
antidote_crdt_register_mv,
57+
antidote_crdt_map_go,
58+
antidote_crdt_map_rr]).
4559

4660
-export([is_type/1
4761
]).

src/antidote_crdt_bcounter.erl renamed to src/antidote_crdt_counter_b.erl

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
%% -*- coding: utf-8 -*-
22
%% --------------------------------------------------------------------------
33
%%
4-
%% crdt_bcounter: A convergent, replicated, operation based bounded counter.
4+
%% antidote_crdt_counter_b: A convergent, replicated, operation-based bounded counter.
55
%%
66
%% --------------------------------------------------------------------------
77

@@ -12,7 +12,7 @@
1212
%% All operations on this CRDT are monotonic and do not keep extra tombstones.
1313
%% @end
1414

15-
-module(antidote_crdt_bcounter).
15+
-module(antidote_crdt_counter_b).
1616

1717
-behaviour(antidote_crdt).
1818

@@ -40,23 +40,23 @@
4040
-include_lib("eunit/include/eunit.hrl").
4141
-endif.
4242

43-
-export_type([bcounter/0, binary_bcounter/0, bcounter_op/0, id/0]).
43+
-export_type([antidote_crdt_counter_b/0, binary_antidote_crdt_counter_b/0, antidote_crdt_counter_b_op/0, id/0]).
4444

45-
-opaque bcounter() :: {orddict:orddict(), orddict:orddict()}.
46-
-type binary_bcounter() :: binary().
47-
-type bcounter_op() :: bcounter_anon_op() | bcounter_src_op().
48-
-type bcounter_anon_op() :: {transfer, {pos_integer(), id(), id()}} |
45+
-opaque antidote_crdt_counter_b() :: {orddict:orddict(), orddict:orddict()}.
46+
-type binary_antidote_crdt_counter_b() :: binary().
47+
-type antidote_crdt_counter_b_op() :: antidote_crdt_counter_b_anon_op() | antidote_crdt_counter_b_src_op().
48+
-type antidote_crdt_counter_b_anon_op() :: {transfer, {pos_integer(), id(), id()}} |
4949
{increment, {pos_integer(), id()}} | {decrement, {pos_integer(), id()}}.
50-
-type bcounter_src_op() :: {bcounter_anon_op(), id()}.
50+
-type antidote_crdt_counter_b_src_op() :: {antidote_crdt_counter_b_anon_op(), id()}.
5151
-opaque id() :: term. %% A replica's identifier.
5252

53-
%% @doc Return a new, empty `bcounter()'.
54-
-spec new() -> bcounter().
53+
%% @doc Return a new, empty `antidote_crdt_counter_b()'.
54+
-spec new() -> antidote_crdt_counter_b().
5555
new() ->
5656
{orddict:new(), orddict:new()}.
5757

58-
%% @doc Return the available permissions of replica `Id' in a `bcounter()'.
59-
-spec localPermissions(id(), bcounter()) -> non_neg_integer().
58+
%% @doc Return the available permissions of replica `Id' in a `antidote_crdt_counter_b()'.
59+
-spec localPermissions(id(), antidote_crdt_counter_b()) -> non_neg_integer().
6060
localPermissions(Id, {P, D}) ->
6161
Received = lists:foldl(
6262
fun(
@@ -88,8 +88,8 @@ localPermissions(Id, {P, D}) ->
8888
Received - Granted
8989
end.
9090

91-
%% @doc Return the total available permissions in a `bcounter()'.
92-
-spec permissions(bcounter()) -> non_neg_integer().
91+
%% @doc Return the total available permissions in a `antidote_crdt_counter_b()'.
92+
-spec permissions(antidote_crdt_counter_b()) -> non_neg_integer().
9393
permissions({P, D}) ->
9494
TotalIncrements = orddict:fold(
9595
fun
@@ -105,22 +105,22 @@ permissions({P, D}) ->
105105
end, 0, D),
106106
TotalIncrements - TotalDecrements.
107107

108-
%% @doc Return the read value of a given `bcounter()', itself.
109-
-spec value(bcounter()) -> bcounter().
108+
%% @doc Return the read value of a given `antidote_crdt_counter_b()', itself.
109+
-spec value(antidote_crdt_counter_b()) -> antidote_crdt_counter_b().
110110
value(Counter) -> Counter.
111111

112112
%% @doc Generate a downstream operation.
113113
%% The first parameter is either `{increment, pos_integer()}' or `{decrement, pos_integer()}',
114114
%% which specify the operation and amount, or `{transfer, pos_integer(), id()}'
115115
%% that additionally specifies the target replica.
116116
%% The second parameter is an `actor()' who identifies the source replica,
117-
%% and the third parameter is a `bcounter()' which holds the current snapshot.
117+
%% and the third parameter is a `antidote_crdt_counter_b()' which holds the current snapshot.
118118
%%
119119
%% Return a tuple containing the operation and source replica.
120120
%% This operation fails and returns `{error, no_permissions}'
121121
%% if it tries to consume resources unavailable to the source replica
122122
%% (which prevents logging of forbidden attempts).
123-
-spec downstream(bcounter_op(), bcounter()) -> {ok, term()} | {error, no_permissions}.
123+
-spec downstream(antidote_crdt_counter_b_op(), antidote_crdt_counter_b()) -> {ok, term()} | {error, no_permissions}.
124124
downstream({increment, {V, Actor}}, _Counter) when is_integer(V), V > 0 ->
125125
{ok, {{increment, V}, Actor}};
126126
downstream({decrement, {V, Actor}}, Counter) when is_integer(V), V > 0 ->
@@ -134,11 +134,11 @@ generate_downstream_check(Op, Actor, Counter, V) ->
134134
Available < V -> {error, no_permissions}
135135
end.
136136

137-
%% @doc Update a `bcounter()' with a downstream operation,
137+
%% @doc Update a `antidote_crdt_counter_b()' with a downstream operation,
138138
%% usually created with `generate_downstream'.
139139
%%
140-
%% Return the resulting `bcounter()' after applying the operation.
141-
-spec update(term(), bcounter()) -> {ok, bcounter()}.
140+
%% Return the resulting `antidote_crdt_counter_b()' after applying the operation.
141+
-spec update(term(), antidote_crdt_counter_b()) -> {ok, antidote_crdt_counter_b()}.
142142
update({{increment, V}, Id}, Counter) ->
143143
increment(Id, V, Counter);
144144
update({{decrement, V}, Id}, Counter) ->
@@ -158,12 +158,12 @@ decrement(Id, V, {P, D}) ->
158158
transfer(From, To, V, {P, D}) ->
159159
{ok, {orddict:update_counter({From, To}, V, P), D}}.
160160

161-
%% doc Return the binary representation of a `bcounter()'.
162-
-spec to_binary(bcounter()) -> binary().
161+
%% doc Return the binary representation of a `antidote_crdt_counter_b()'.
162+
-spec to_binary(antidote_crdt_counter_b()) -> binary().
163163
to_binary(C) -> term_to_binary(C).
164164

165-
%% doc Return a `bcounter()' from its binary representation.
166-
-spec from_binary(binary()) -> {ok, bcounter()}.
165+
%% doc Return a `antidote_crdt_counter_b()' from its binary representation.
166+
-spec from_binary(binary()) -> {ok, antidote_crdt_counter_b()}.
167167
from_binary(<<B/binary>>) -> {ok, binary_to_term(B)}.
168168

169169
%% @doc The following operation verifies
@@ -199,7 +199,7 @@ apply_op(Op, Counter) ->
199199
{ok, NewCounter} = update(OP_DS, Counter),
200200
NewCounter.
201201

202-
%% Tests creating a new `bcounter()'.
202+
%% Tests creating a new `antidote_crdt_counter_b()'.
203203
new_test() ->
204204
?assertEqual({[], []}, new()).
205205

@@ -271,22 +271,22 @@ transfer_test() ->
271271

272272
%% Tests the function `value()'.
273273
value_test() ->
274-
%% Test on `bcounter()' resulting from applying all kinds of operation.
274+
%% Test on `antidote_crdt_counter_b()' resulting from applying all kinds of operation.
275275
Counter0 = new(),
276276
Counter1 = apply_op({increment, {10, r1}}, Counter0),
277277
Counter2 = apply_op({decrement, {6, r1}}, Counter1),
278278
Counter3 = apply_op({transfer, {2, r2, r1}}, Counter2),
279-
%% Assert `value()' returns `bcounter()' itself.
279+
%% Assert `value()' returns `antidote_crdt_counter_b()' itself.
280280
?assertEqual(Counter3, value(Counter3)).
281281

282282
%% Tests serialization functions `to_binary()' and `from_binary()'.
283283
binary_test() ->
284-
%% Test on `bcounter()' resulting from applying all kinds of operation.
284+
%% Test on `antidote_crdt_counter_b()' resulting from applying all kinds of operation.
285285
Counter0 = new(),
286286
Counter1 = apply_op({increment, {10, r1}}, Counter0),
287287
Counter2 = apply_op({decrement, {6, r1}}, Counter1),
288288
Counter3 = apply_op({transfer, {2, r2, r1}}, Counter2),
289-
%% Assert marshaling and unmarshaling holds the same `bcounter()'.
289+
%% Assert marshaling and unmarshaling holds the same `antidote_crdt_counter_b()'.
290290
B = to_binary(Counter3),
291291
?assertEqual({ok, Counter3}, from_binary(B)).
292292

src/antidote_crdt_fat_counter.erl renamed to src/antidote_crdt_counter_fat.erl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,17 @@
1818
%%
1919
%% -------------------------------------------------------------------
2020

21-
%% antidote_crdt_fat_counter: A convergent, replicated, operation based Fat Counter
21+
%% antidote_crdt_counter_fat: A convergent, replicated, operation based Fat Counter
2222
%% The state of this fat counter is list of pairs where each pair is an integer
2323
%% and a related token.
2424
%% Basically when the counter recieves {increment, N} or {decrement, N} it generates
2525
%% a pair {N, NewToken}.
2626
%% On update, all seen tokens are removed and the new pair is then added to the state.
2727
%% This token keeps growing ("Fat" Counter) but it useful as it allows the reset
2828
%% functionaility, On reset(), all seen tokens are removed.
29+
%% link to paper: http://haslab.uminho.pt/cbm/files/a3-younes.pdf
2930

30-
-module(antidote_crdt_fat_counter).
31+
-module(antidote_crdt_counter_fat).
3132

3233
-behaviour(antidote_crdt).
3334

src/antidote_crdt_counter.erl renamed to src/antidote_crdt_counter_pn.erl

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,13 @@
1818
%%
1919
%% -------------------------------------------------------------------
2020

21-
%% antidote_crdt_pncounter: A convergent, replicated, operation
21+
%% antidote_crdt_counter_pn: A convergent, replicated, operation
2222
%% based PN-Counter
2323

24-
-module(antidote_crdt_counter).
24+
-module(antidote_crdt_counter_pn).
2525

2626
-behaviour(antidote_crdt).
2727

28-
-include("antidote_crdt.hrl").
29-
3028
-ifdef(TEST).
3129
-include_lib("eunit/include/eunit.hrl").
3230
-endif.
@@ -43,27 +41,33 @@
4341
require_state_downstream/1
4442
]).
4543

46-
%% @doc Create a new, empty 'pncounter()'
44+
45+
-type state() :: integer().
46+
-type op() :: {increment, integer()} |
47+
{decrement, integer()}.
48+
-type effect() :: integer().
49+
50+
%% @doc Create a new, empty 'antidote_crdt_counter_pn'
4751
new() ->
4852
0.
4953

50-
%% @doc Create 'pncounter()' with initial value
51-
-spec new(integer()) -> pncounter().
54+
%% @doc Create 'antidote_crdt_counter_pn' with initial value
55+
-spec new(integer()) -> state().
5256
new(Value) when is_integer(Value) ->
5357
Value;
5458
new(_) ->
5559
new().
5660

5761
%% @doc The single, total value of a `pncounter()'
58-
-spec value(pncounter()) -> integer().
62+
-spec value(state()) -> integer().
5963
value(PNCnt) when is_integer(PNCnt) ->
6064
PNCnt.
6165

6266
%% @doc Generate a downstream operation.
6367
%% The first parameter is either `increment' or `decrement' or the two tuples
6468
%% `{increment, pos_integer()}' or `{decrement, pos_integer()}'. The second parameter
6569
%% is the pncounter (this parameter is not actually used).
66-
-spec downstream(pncounter_update(), pncounter()) -> {ok, pncounter_effect()}.
70+
-spec downstream(op(), state()) -> {ok, effect()}.
6771
downstream(increment, _PNCnt) ->
6872
{ok, 1};
6973
downstream(decrement, _PNCnt) ->
@@ -81,17 +85,17 @@ downstream({decrement, By}, _PNCnt) when is_integer(By) ->
8185
%% The 2nd argument is the `pncounter()' to update.
8286
%%
8387
%% returns the updated `pncounter()'
84-
-spec update(pncounter_effect(), pncounter()) -> {ok, pncounter()}.
88+
-spec update(effect(), state()) -> {ok, state()}.
8589
update(N, PNCnt) ->
8690
{ok, PNCnt + N}.
8791

8892
%% @doc Compare if two `pncounter()' are equal. Only returns `true()' if both
8993
%% of their positive and negative entries are equal.
90-
-spec equal(pncounter(), pncounter()) -> boolean().
94+
-spec equal(state(), state()) -> boolean().
9195
equal(PNCnt1, PNCnt2) ->
9296
PNCnt1 =:= PNCnt2.
9397

94-
-spec to_binary(pncounter()) -> binary().
98+
-spec to_binary(state()) -> binary().
9599
to_binary(PNCounter) ->
96100
term_to_binary(PNCounter).
97101

src/antidote_crdt_flag_dw.erl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@
4747
-define(V1_VERS, 1).
4848

4949
-export_type([flag_dw/0]).
50-
-opaque flag_dw() :: {antidote_crdt_flag:tokens(), antidote_crdt_flag:tokens()}.
50+
-opaque flag_dw() :: {antidote_crdt_flag_helper:tokens(), antidote_crdt_flag_helper:tokens()}.
5151

5252
%% SeenTokens, NewEnableTokens, NewDisableTokens
53-
-type downstream_op() :: {antidote_crdt_flag:tokens(), antidote_crdt_flag:tokens(), antidote_crdt_flag:tokens()}.
53+
-type downstream_op() :: {antidote_crdt_flag_helper:tokens(), antidote_crdt_flag_helper:tokens(), antidote_crdt_flag_helper:tokens()}.
5454

5555
-spec new() -> flag_dw().
5656
new() ->
@@ -60,11 +60,11 @@ new() ->
6060
value({EnableTokens, DisableTokens}) ->
6161
DisableTokens == [] andalso EnableTokens =/= [].
6262

63-
-spec downstream(antidote_crdt_flag:op(), flag_dw()) -> {ok, downstream_op()}.
63+
-spec downstream(antidote_crdt_flag_helper:op(), flag_dw()) -> {ok, downstream_op()}.
6464
downstream({disable, {}}, {EnableTokens, DisableTokens}) ->
65-
{ok, {EnableTokens ++ DisableTokens, [], [antidote_crdt_flag:unique()]}};
65+
{ok, {EnableTokens ++ DisableTokens, [], [antidote_crdt_flag_helper:unique()]}};
6666
downstream({enable, {}}, {EnableTokens, DisableTokens}) ->
67-
{ok, {EnableTokens ++ DisableTokens, [antidote_crdt_flag:unique()], []}};
67+
{ok, {EnableTokens ++ DisableTokens, [antidote_crdt_flag_helper:unique()], []}};
6868
downstream({reset, {}}, {EnableTokens, DisableTokens}) ->
6969
{ok, {EnableTokens ++ DisableTokens, [], []}}.
7070

@@ -78,7 +78,7 @@ downstream({reset, {}}, {EnableTokens, DisableTokens}) ->
7878
equal(Flag1, Flag2) ->
7979
Flag1 == Flag2.
8080

81-
-spec to_binary(flag_dw()) -> antidote_crdt_flag:binary_flag().
81+
-spec to_binary(flag_dw()) -> antidote_crdt_flag_helper:binary_flag().
8282
to_binary(Flag) ->
8383
%% @TODO something smarter
8484
<<?TAG:8/integer, ?V1_VERS:8/integer, (term_to_binary(Flag))/binary>>.
@@ -87,12 +87,12 @@ from_binary(<<?TAG:8/integer, ?V1_VERS:8/integer, Bin/binary>>) ->
8787
%% @TODO something smarter
8888
{ok, binary_to_term(Bin)}.
8989

90-
is_operation(A) -> antidote_crdt_flag:is_operation(A).
90+
is_operation(A) -> antidote_crdt_flag_helper:is_operation(A).
9191

9292
is_bottom(Flag) ->
9393
Flag == new().
9494

95-
require_state_downstream(A) -> antidote_crdt_flag:require_state_downstream(A).
95+
require_state_downstream(A) -> antidote_crdt_flag_helper:require_state_downstream(A).
9696

9797

9898
%% ===================================================================

0 commit comments

Comments
 (0)