Skip to content

Instantly share code, notes, and snippets.

@fswalker
Created May 4, 2017 08:50
Show Gist options
  • Save fswalker/d458046e0ba583a3d1fd418f765755cf to your computer and use it in GitHub Desktop.
Save fswalker/d458046e0ba583a3d1fd418f765755cf to your computer and use it in GitHub Desktop.
%% Based on code from
%% Erlang Programming
%% Francecso Cesarini and Simon Thompson
%% O'Reilly, 2008
%% http://oreilly.com/catalog/9780596518189/
%% http://www.erlangprogramming.org/
%% (c) Francesco Cesarini and Simon Thompson
-module(gf).
-behaviour(gen_server).
% an implementation of this is included.
-export([start_link/0]).
% you need to implement these functions.
-export([init/1, handle_call/3, handle_cast/2]).
% these are implemented for you.
-export([handle_info/2, terminate/2, code_change/3]).
% you will need to implement these.
-export([allocate/0,deallocate/1,stop/0]).
-export([run_simulation/0]).
%% These are the start functions used to create and
%% initialize the server.
start_link() ->
gen_server:start_link(
{local, ?MODULE},
?MODULE, [], []).
init([]) ->
Frequencies = {get_frequencies(), []},
{ok, Frequencies}.
% Hard Coded
get_frequencies() -> [10,11,12,13,14,15].
%% Functional interface
allocate() ->
gen_server:call(?MODULE, allocate).
deallocate(Freq) ->
gen_server:cast(?MODULE, {deallocate, Freq}).
report() ->
gen_server:call(?MODULE, report).
add(Freqs) ->
gen_server:call(?MODULE, {add, Freqs}).
stop() ->
gen_server:stop(?MODULE).
handle_call(allocate, From, State) ->
{NewState, Reply} = allocate(State, From),
{reply, Reply, NewState};
handle_call(report, _From, State) ->
{Free, Allocated} = State,
FreeNum = length(Free),
AllocatedNum = length(Allocated),
{reply, {{'Free', FreeNum}, {'Allocated', AllocatedNum}}, State};
handle_call({add, []}, _From, State) ->
{reply, error, State};
handle_call({add, NewFreqs}, _From, State) ->
{Free, Allocated} = State,
SortedFree = lists:usort(Free),
SortedNewFreqs = lists:usort(NewFreqs),
SortedNewFree = lists:umerge(SortedNewFreqs, SortedFree),
FreeHasNoDuplicates = length(SortedFree) == length(Free),
NewFreqsHasNoDuplicates = length(SortedNewFreqs) == length(NewFreqs),
NewFreeHasNoDuplicates = length(SortedNewFree) == length(SortedNewFreqs ++ SortedFree),
if
FreeHasNoDuplicates andalso NewFreqsHasNoDuplicates andalso NewFreeHasNoDuplicates ->
{reply, ok, {SortedNewFree, Allocated}};
true ->
{reply, error, State}
end.
handle_cast({deallocate, Freq}, State) ->
NewState = deallocate(State, Freq),
{noreply, NewState}.
%% The Internal Help Functions used to allocate and
%% deallocate frequencies.
allocate({[], Allocated}, _Pid) ->
{{[], Allocated}, {error, no_frequency}};
allocate({[Freq|Free], Allocated}, Pid) ->
{{Free, [{Freq, Pid}|Allocated]}, {ok, Freq}}.
deallocate({Free, Allocated}, Freq) ->
NewAllocated=lists:keydelete(Freq, 1, Allocated),
{[Freq|Free], NewAllocated}.
% default implementations
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
run_simulation() ->
S1 = start_link(),
io:format("Start: ~p~n", [S1]),
io:format("Report: ~p~n", [report()]),
timer:sleep(1000),
S2 = allocate(),
io:format("Allocate: ~p~n", [S2]),
io:format("Report: ~p~n", [report()]),
timer:sleep(1000),
S3 = allocate(),
io:format("Allocate: ~p~n", [S3]),
io:format("Report: ~p~n", [report()]),
timer:sleep(1000),
S4 = allocate(),
io:format("Allocate: ~p~n", [S4]),
io:format("Report: ~p~n", [report()]),
timer:sleep(1000),
S5 = deallocate(11),
io:format("Deallocate (11): ~p~n", [S5]),
io:format("Report: ~p~n", [report()]),
timer:sleep(1000),
S6 = allocate(),
io:format("Allocate: ~p~n", [S6]),
io:format("Report: ~p~n", [report()]),
timer:sleep(1000),
S7 = add([]),
io:format("Add []: ~p~n", [S7]),
io:format("Report: ~p~n", [report()]),
timer:sleep(1000),
NewFreqs = [20,21,22],
S8 = add(NewFreqs),
io:format("Add ~p: ~p~n", [NewFreqs, S8]),
io:format("Report: ~p~n", [report()]),
timer:sleep(1000),
S9 = stop(),
io:format("Stop: ~p~n", [S9]).
% c(gf).
% gf:run_simulation().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment