Skip to content

Instantly share code, notes, and snippets.

@blackheaven
Created March 3, 2014 12:03
Show Gist options
  • Save blackheaven/9323637 to your computer and use it in GitHub Desktop.
Save blackheaven/9323637 to your computer and use it in GitHub Desktop.
-module(list).
-export([merger/0, atomic_sort/0, accumulator/0, last/1, init/0, add/2, get/1]).
atomic_sort() ->
receive
{L, Accumulator, Merger, Last} ->
Accumulator ! {lists:sort(L), Merger, Last},
atomic_sort()
end.
accumulator() ->
receive
{L, _, _} ->
% io:format("~p : ~p~n", ["acc0", L]),
accumulator(L)
end.
accumulator(L1) ->
receive
{L2, Merger, Last} ->
% io:format("~p : ~p~n", ["acc1", L2]),
Merger ! {L1, L2, self(), Last},
accumulator()
end.
merger() ->
receive
{L1, L2, Accumulator, Last} ->
L = merge(L1, L2),
% io:format("~p : ~p~n", ["merge", L]),
Accumulator ! {L, self(), Last},
Last ! {set, L},
merger()
end.
merge([], X) -> X;
merge(X, []) -> X;
merge([X|XS], [Y|YS]) ->
case X > Y of
true -> [Y | merge([X|XS], YS)];
_ -> [X | merge(XS, [Y|YS])]
end.
last(C) ->
receive
{set, N} ->
% io:format("~p : ~p~n", ["last", N]),
last(N);
{get, A} ->
A ! C,
last(C)
end.
init() ->
A = spawn(?MODULE, accumulator, []),
A ! {[], nil, nil},
S = spawn(?MODULE, atomic_sort, []),
M = spawn(?MODULE, merger, []),
L = spawn(?MODULE, last, [[]]),
{S, A, M, L}.
add(List, {S, A, M, L}) ->
S ! {List, A, M, L}
.
get({_, _, _, L}) ->
L ! {get, self()},
receive
R -> R
end;
get(L) ->
L ! {get, self()},
receive
R -> R
end.
-module(list_tests).
-include_lib("eunit/include/eunit.hrl").
empty_test() ->
P = list:init(),
?assertEqual([], list:get(P)).
empty_one_var_test() ->
{_, _, _, L} = list:init(),
?assertEqual([], list:get(L)).
add_one_ordered_set_test() ->
P = list:init(),
list:add([1, 2], P),
timer:sleep(5),
?assertEqual([1, 2], list:get(P)).
add_one_unordered_set_test() ->
P = list:init(),
list:add([2, 1], P),
timer:sleep(5),
?assertEqual([1, 2], list:get(P)).
add_two_sets_test() ->
P = list:init(),
list:add([5, 4], P),
list:add([1, 8], P),
timer:sleep(5),
?assertEqual([1, 4, 5, 8], list:get(P)).
add_three_sets_test() ->
P = list:init(),
list:add([9], P),
list:add([5, 4], P),
list:add([1, 8], P),
timer:sleep(5),
?assertEqual([1, 4, 5, 8, 9], list:get(P)).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment