Created
July 14, 2020 22:59
-
-
Save tecnowilliam/32e44fa3479882e98333d4f1eceece77 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| % Compile: c(gs_frequency). | |
| -module(gs_frequency). | |
| -author("William Vargas"). | |
| -version("1.0"). | |
| -behaviour(gen_server). | |
| % API | |
| -export([start_link/0, get/0, add/1, allocate/0, deallocate/1, reset/0, stop/0]). | |
| % gen_server | |
| -export([init/1, handle_call/3, handle_cast/2]). | |
| % Start the frequency server | |
| -spec start_link() -> pid(). | |
| start_link() -> | |
| gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). | |
| % Initialize the server | |
| -spec init(list()) -> {ok,list()}. | |
| init([]) -> | |
| Frequencies = {get_frequencies(), []}, | |
| {ok, Frequencies}. | |
| % Get the default frequencies | |
| -spec get_frequencies() -> list(). | |
| get_frequencies() -> | |
| [1,2,3,4,5,6,7,8,9,10]. | |
| % gen_server:call | |
| -spec get() -> any(). | |
| get() -> | |
| gen_server:call(?MODULE, get). | |
| -spec add(integer()) -> any(). | |
| add(Freq) -> | |
| gen_server:call(?MODULE, {add, Freq}). | |
| -spec allocate() -> any(). | |
| allocate() -> | |
| gen_server:call(?MODULE, allocate). | |
| -spec deallocate(integer()) -> any(). | |
| deallocate(Freq) -> | |
| gen_server:call(?MODULE, {deallocate, Freq}). | |
| % gen_server:cast | |
| -spec reset() -> any(). | |
| reset() -> | |
| gen_server:cast(?MODULE, reset). | |
| -spec stop() -> any(). | |
| stop() -> | |
| gen_server:cast(?MODULE, stop). | |
| % gen_server handle_call | |
| handle_call(get, _From, Freqs) -> | |
| {reply, Freqs, Freqs}; | |
| handle_call({add, Freq}, _From, Freqs) -> | |
| {NewFreqs, Reply} = add(Freqs, Freq), | |
| {reply, Reply, NewFreqs}; | |
| handle_call(allocate, From, Freqs) -> | |
| {NewFreqs, Reply} = allocate(Freqs, From), | |
| {reply, Reply, NewFreqs}; | |
| handle_call({deallocate, Freq}, _From, Freqs) -> | |
| {NewFreqs, Reply} = deallocate(Freqs, Freq), | |
| {reply, Reply, NewFreqs}. | |
| % gen_server handle_cast | |
| handle_cast(reset, _State) -> | |
| {noreply, {get_frequencies(), []}}; | |
| handle_cast(stop, _State) -> | |
| gen_server:stop(?MODULE). | |
| % Add a new frequency | |
| -spec add({list(),list()}, integer()) -> {{list(),list()},{atom(), atom()|integer()}}. | |
| add({Free, Allocated}, Freq) -> | |
| case lists:keyfind(Freq, 1, Allocated) of | |
| {Freq, _Pid} -> | |
| {{Free, Allocated}, {error, frequency_exists}}; | |
| _ -> | |
| case lists:member(Freq, Free) of | |
| true -> | |
| {{Free, Allocated}, {error, frequency_exists}}; | |
| _ -> | |
| {{lists:append(Free,[Freq]), Allocated}, {ok, Freq}} | |
| end | |
| end. | |
| % Allocate a frequency | |
| -spec allocate({list(), list()}, pid()) -> {{list(),list()},{atom(), atom()|integer()}}. | |
| allocate({[], Allocated}, _Pid) -> | |
| {{[], Allocated}, {error, no_frequency}}; | |
| allocate({[Freq|Free], Allocated}, Pid) -> | |
| {{Free, [{Freq, Pid}|Allocated]}, {ok, Freq}}. | |
| % Deallocate a frequency | |
| -spec deallocate({list(), list()}, integer()) -> {{list(),list()},{atom(), atom()|integer()}}. | |
| deallocate({Free, Allocated}, Freq) -> | |
| case lists:keyfind(Freq, 1, Allocated) of | |
| {Freq, Pid} -> | |
| NewAllocated = lists:delete({Freq, Pid}, Allocated), | |
| {{[Freq|Free], NewAllocated}, {ok, Freq}}; | |
| _ -> | |
| {{Free, Allocated}, {error, frequency_not_exists}} | |
| end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment