/
fn_server.erl
59 lines (51 loc) · 1.36 KB
/
fn_server.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
-module(fn_server).
-export([start/0, stop/0, set/2, get/1, server/1]).
start() ->
case whereis(fn_server) of
undefined ->
Pid = spawn(?MODULE, server, [dict:new()]),
register(fn_server, Pid),
Pid;
P -> P
end.
stop() ->
fn_server ! stop.
set(Key, Value) ->
fn_server ! {set, self(), Key, Value},
ok.
get(Key) ->
fn_server ! {get, self(), Key},
receive
{ok, _Val} = Response -> Response;
error -> error
end.
server(Data) ->
receive
stop ->
normal;
{set, Pid, Key, Value} ->
NewData = store(Pid, Data, Key, Value),
server(NewData);
{get, Pid, Key} ->
Pid ! fetch(Pid, Data, Key),
server(Data)
end.
store(Pid, Dict, Key, Value) ->
case dict:is_key(Pid, Dict) of
true ->
PidDict = dict:fetch(Pid, Dict),
NewPidDict = dict:store(Key, Value, PidDict),
dict:store(Pid, NewPidDict, Dict);
false ->
PidDict = dict:new(),
NewPidDict = dict:store(Key, Value, PidDict),
dict:store(Pid, NewPidDict, Dict)
end.
fetch(Pid, Dict, Key) ->
case dict:is_key(Pid, Dict) of
true ->
PidDict = dict:fetch(Pid, Dict),
dict:find(Key, PidDict);
false ->
error
end.