Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Licenser committed May 25, 2013
0 parents commit a346b7b
Show file tree
Hide file tree
Showing 14 changed files with 956 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
erl_crash.dump
ebin
.eunit
deps
priv
*.o
*.beam
*.plt
383 changes: 383 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

70 changes: 70 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
REBAR = $(shell pwd)/rebar

.PHONY: deps rel package

all: deps compile

compile:
$(REBAR) compile

deps:
$(REBAR) get-deps

clean:
$(REBAR) clean

distclean: clean
$(REBAR) delete-deps

test: all
$(REBAR) skip_deps=true eunit

###
### Docs
###
docs:
$(REBAR) skip_deps=true doc

##
## Developer targets
##

xref:
$(REBAR) xref skip_deps=true

console: all
erl -pa ebin deps/*/ebin


##
## Dialyzer
##
APPS = kernel stdlib sasl erts ssl tools os_mon runtime_tools crypto inets \
xmerl webtool snmp public_key mnesia eunit syntax_tools compiler
COMBO_PLT = $(HOME)/.ecrdt_combo_dialyzer_plt


check_plt: deps compile
dialyzer --check_plt --plt $(COMBO_PLT) --apps $(APPS) \
deps/*/ebin ebin

build_plt: deps compile
dialyzer --build_plt --output_plt $(COMBO_PLT) --apps $(APPS) \
deps/*/ebin ebin

dialyzer: deps compile
@echo
@echo Use "'make check_plt'" to check PLT prior to using this target.
@echo Use "'make build_plt'" to build PLT prior to using this target.
@echo
@sleep 1
dialyzer -Wno_return --plt $(COMBO_PLT) deps/*/ebin ebin | grep -v -f dialyzer.mittigate


cleanplt:
@echo
@echo "Are you sure? It takes about 1/2 hour to re-build."
@echo Deleting $(COMBO_PLT) in 5 seconds.
@echo
sleep 5
rm $(COMBO_PLT)
Binary file added rebar
Binary file not shown.
5 changes: 5 additions & 0 deletions rebar.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{erl_opts, [debug_info, warnings_as_errors]}.
{deps,
[
{proper, ".*", {git, "git://github.com/manopapad/proper.git", {branch, master}}}
]}.
96 changes: 96 additions & 0 deletions src/#sgset.erl#
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
-module(sgset).

-ifdef(TEST).
-include_lib("proper/include/proper.hrl").
-include_lib("eunit/include/eunit.hrl").
-endif.

-export([new/0, add/2, merge/2, value/1]).

-record(sgset, {payload = []}).

-opaque sgset() :: #sgset{}.

-export_type([sgset/0]).

%%--------------------------------------------------------------------
%% @doc
%% Creates a new empty Sgset (only growing set)
%% @end
%%--------------------------------------------------------------------

-spec new() -> sgset().

new() ->
#sgset{}.

%%--------------------------------------------------------------------
%% @doc
%% Adds an element to the Sgset.
%% @end
%%--------------------------------------------------------------------
-spec add(Element::term(), Sgset::sgset()) -> Sgset1::sgset().

add(Element, #sgset{payload = Payload}) ->
#sgset{payload = ordsets:add_element(Element, Payload)}.

%%--------------------------------------------------------------------
%% @doc
%% Merges tow Sgsets.
%% @end
%%--------------------------------------------------------------------
-spec merge(Sgset1::sgset(), Sgset2::sgset()) -> Sgset::sgset().

merge(#sgset{payload = Payload1}, #sgset{payload = Payload2}) ->
#sgset{payload = ordsets:union(Payload1, Payload2)}.


%%--------------------------------------------------------------------
%% @doc
%% Gets the raw value of a sgset.
%% @end
%%--------------------------------------------------------------------
-spec value(Sgset::sgset()) -> [Element::term()].

value(#sgset{payload = Payload}) ->
Payload.


%%%===================================================================
%%% Tests
%%%===================================================================

-ifdef(TEST).

%% Apply a option either to the first set the second one or both.
%% Also keeps track of all changes in a check set (3rd).
op(a, E, Sgset1, Sgset2, Check) ->
{add(E, Sgset1), Sgset2, add(E, Check)};

op(b, E, Sgset1, Sgset2, Check) ->
{Sgset1, add(E, Sgset2), add(E, Check)};

op(ab, E, Sgset1, Sgset2, Check) ->
{add(E, Sgset1), add(E, Sgset2), add(E, Check)}.

%% Applies the list of opperaitons to three empty sets.
apply_ops(Ops) ->
lists:foldl(fun({T, E}, {A, B, C}) ->
op(T, E, A, B, C)
end, {new(), new(), new()}, Ops).

%% A list of opperations and targets.
targets() ->
list({oneof([a, b, ab]), integer()}).

prop_sgset() ->
?FORALL(Ts, targets(),
begin
{A, B, C} = apply_ops(Ts),
value(C) =:= value(merge(A, B))
end).

propper_test() ->
?assertEqual([], proper:module(?MODULE, [{to_file, user}, long_result])).

-endif.
1 change: 1 addition & 0 deletions src/.#sgset.erl
12 changes: 12 additions & 0 deletions src/ecrdt.app.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{application, ecrdt,
[
{description, ""},
{vsn, "1"},
{registered, []},
{applications, [
kernel,
stdlib
]},
{mod, { ecrdt_app, []}},
{env, []}
]}.
16 changes: 16 additions & 0 deletions src/ecrdt_app.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-module(ecrdt_app).

-behaviour(application).

%% Application callbacks
-export([start/2, stop/1]).

%% ===================================================================
%% Application callbacks
%% ===================================================================

start(_StartType, _StartArgs) ->
ecrdt_sup:start_link().

stop(_State) ->
ok.
28 changes: 28 additions & 0 deletions src/ecrdt_sup.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

-module(ecrdt_sup).

-behaviour(supervisor).

%% API
-export([start_link/0]).

%% Supervisor callbacks
-export([init/1]).

%% Helper macro for declaring children of supervisor
-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}).

%% ===================================================================
%% API functions
%% ===================================================================

start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).

%% ===================================================================
%% Supervisor callbacks
%% ===================================================================

init([]) ->
{ok, { {one_for_one, 5, 10}, []} }.

77 changes: 77 additions & 0 deletions src/mmcounter.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
-module(mmcounter).

-ifdef(TEST).
-include_lib("proper/include/proper.hrl").
-include_lib("eunit/include/eunit.hrl").
-endif.

-export([new/1, value/1, inc/3, dec/3, merge/2]).

-record(mmcounter, {inc_counter, dec_counter}).


new(Size) ->
#mmcounter{
inc_counter = mmicounter:new(Size),
dec_counter = mmicounter:new(Size)
}.

inc(Master, Increment,
Counter = #mmcounter{inc_counter = Inc}) ->
Counter#mmcounter{
inc_counter = mmicounter:inc(Master, Increment, Inc)
}.

dec(Master, Increment,
Counter = #mmcounter{dec_counter = Dec}) ->
Counter#mmcounter{
dec_counter = mmicounter:inc(Master, Increment, Dec)
}.

value(#mmcounter{dec_counter = Dec,
inc_counter = Inc}) ->
mmicounter:value(Inc) - mmicounter:value(Dec).

merge(#mmcounter{dec_counter = Dec0,
inc_counter = Inc0},
#mmcounter{dec_counter = Dec1,
inc_counter = Inc1}) ->
#mmcounter{dec_counter = mmicounter:merge(Dec0, Dec1),
inc_counter = mmicounter:merge(Inc0, Inc1)}.


-ifdef(TEST).

op(a, inc, E, C1, C2, Check) ->
{inc(1, E, C1), C2, inc(1, E, Check)};

op(b, inc, E, C1, C2, Check) ->
{C1, inc(2, E, C2), inc(2, E, Check)};

op(a, dec, E, C1, C2, Check) ->
{dec(1, E, C1), C2, dec(1, E, Check)};

op(b, dec, E, C1, C2, Check) ->
{C1, dec(2, E, C2), dec(2, E, Check)}.

%% Applies the list of opperaitons to three empty sets.
apply_ops(Ops) ->
lists:foldl(fun({T, O, E}, {A, B, C}) ->
op(T, O, E, A, B, C)
end, {new(2), new(2), new(2)}, Ops).

%% A list of opperations and targets.
targets() ->
list({oneof([a, b]), oneof([inc, dec]), pos_integer()}).

prop_mmicounter() ->
?FORALL(Ts, targets(),
begin
{A, B, C} = apply_ops(Ts),
C =:= merge(A, B)
end).

propper_test() ->
?assertEqual([], proper:module(?MODULE, [{to_file, user}, long_result])).

-endif.
76 changes: 76 additions & 0 deletions src/mmicounter.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
-module(mmicounter).

-ifdef(TEST).
-include_lib("proper/include/proper.hrl").
-include_lib("eunit/include/eunit.hrl").
-endif.

-export([new/1, value/1, inc/3, merge/2]).

-record(mmicounter, {vector, size}).

new(Size) ->
L = [ 0 || _ <- lists:seq(1, Size)],
#mmicounter{size = Size, vector = list_to_tuple(L)}.


inc(Master, Increment,
Counter = #mmicounter{vector = Vector0,
size = _Size}) when Increment > 0,
Master =< _Size ->
Value0 = element(Master, Vector0),
Value1 = Value0 + Increment,
Vector1 = setelement(Master, Vector0, Value1),
Counter#mmicounter{vector = Vector1}.

merge(Counter0 = #mmicounter{vector = Vector0, size = _Size},
#mmicounter{vector = Vector1, size = _Size}) ->
VectorM = list_to_tuple(
merge_vecotrs(tuple_to_list(Vector0),
tuple_to_list(Vector1),
[])),
Counter0#mmicounter{vector = VectorM}.

value(#mmicounter{vector = Vector0}) ->
Vector1 = tuple_to_list(Vector0),
lists:foldl(fun(V, Acc) ->
Acc + V
end, 0, Vector1).

merge_vecotrs([V0 | R0], [_V1 | R1], Acc) when V0 >= _V1 ->
merge_vecotrs(R0, R1, [V0 | Acc]);
merge_vecotrs([_ | R0], [V1 | R1], Acc) ->
merge_vecotrs(R0, R1, [V1 | Acc]);
merge_vecotrs([], [], Acc) ->
lists:reverse(Acc).


-ifdef(TEST).

op(a, E, C1, C2, Check) ->
{inc(1, E, C1), C2, inc(1, E, Check)};

op(b, E, C1, C2, Check) ->
{C1, inc(2, E, C2), inc(2, E, Check)}.

%% Applies the list of opperaitons to three empty sets.
apply_ops(Ops) ->
lists:foldl(fun({T, E}, {A, B, C}) ->
op(T, E, A, B, C)
end, {new(2), new(2), new(2)}, Ops).

%% A list of opperations and targets.
targets() ->
list({oneof([a, b]), pos_integer()}).

prop_mmicounter() ->
?FORALL(Ts, targets(),
begin
{A, B, C} = apply_ops(Ts),
value(C) =:= value(merge(A, B))
end).

propper_test() ->
?assertEqual([], proper:module(?MODULE, [{to_file, user}, long_result])).

-endif.
Loading

0 comments on commit a346b7b

Please sign in to comment.