From bebce51ab927b4bd052028b869ff95b00e665244 Mon Sep 17 00:00:00 2001 From: Scott Lystig Fritchie Date: Sun, 28 Sep 2014 15:01:12 +0900 Subject: [PATCH] WIP: minimal write-once projection store in FLU --- prototype/poc-machi/src/machi_flu0.erl | 62 +++++++++++++++++++- prototype/poc-machi/test/machi_flu0_test.erl | 15 +++++ 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/prototype/poc-machi/src/machi_flu0.erl b/prototype/poc-machi/src/machi_flu0.erl index 463d3c9..e4704fe 100644 --- a/prototype/poc-machi/src/machi_flu0.erl +++ b/prototype/poc-machi/src/machi_flu0.erl @@ -3,7 +3,8 @@ -behaviour(gen_server). -export([start_link/1, stop/1, - write/2, get/1, trim/1]). + write/2, get/1, trim/1, + proj_write/3, proj_read/2, proj_get_latest_num/1, proj_read_latest/1]). -ifdef(TEST). -compile(export_all). -endif. @@ -28,7 +29,8 @@ -record(state, { name :: list(), - register = 'unwritten' :: register() + register = 'unwritten' :: register(), + proj_store :: dict() }). start_link(Name) when is_list(Name) -> @@ -46,10 +48,22 @@ write(Pid, Bin) when is_binary(Bin) -> trim(Pid) -> gen_server:call(Pid, {trim}, ?LONG_TIME). +proj_write(Pid, Num, Proj) -> + gen_server:call(Pid, {proj_write, Num, Proj}, ?LONG_TIME). + +proj_read(Pid, Num) -> + gen_server:call(Pid, {proj_read, Num}, ?LONG_TIME). + +proj_get_latest_num(Pid) -> + gen_server:call(Pid, {proj_get_latest_num}, ?LONG_TIME). + +proj_read_latest(Pid) -> + gen_server:call(Pid, {proj_read_latest}, ?LONG_TIME). + %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% init([Name]) -> - {ok, #state{name=Name}}. + {ok, #state{name=Name, proj_store=orddict:new()}}. handle_call({write, Bin}, _From, #state{register=unwritten} = S) -> {reply, ok, S#state{register=Bin}}; @@ -65,6 +79,23 @@ handle_call({trim}, _From, #state{register=B} = S) when is_binary(B) -> {reply, ok, S#state{register=trimmed}}; handle_call({trim}, _From, #state{register=trimmed} = S) -> {reply, error_trimmed, S}; +handle_call({proj_write, Num, Proj}, _From, S) -> + {Reply, NewS} = do_proj_write(Num, Proj, S), + {reply, Reply, NewS}; +handle_call({proj_read, Num}, _From, S) -> + {Reply, NewS} = do_proj_read(Num, S), + {reply, Reply, NewS}; +handle_call({proj_get_latest_num}, _From, S) -> + {Reply, NewS} = do_proj_get_latest_num(S), + {reply, Reply, NewS}; +handle_call({proj_read_latest}, _From, S) -> + case do_proj_get_latest_num(S) of + {error_unwritten, _S} -> + {reply, error_unwritten, S}; + {{ok, Num}, _S} -> + Proj = orddict:fetch(Num, S#state.proj_store), + {reply, {ok, Proj}, S} + end; handle_call(stop, _From, MLP) -> {stop, normal, ok, MLP}; handle_call(_Request, _From, MLP) -> @@ -85,3 +116,28 @@ code_change(_OldVsn, MLP, _Extra) -> %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% %%%% +do_proj_write(Num, Proj, #state{proj_store=D} = S) -> + case orddict:find(Num, D) of + error -> + D2 = orddict:store(Num, Proj, D), + {ok, S#state{proj_store=D2}}; + {ok, _} -> + {error_written, S} + end. + +do_proj_read(Num, #state{proj_store=D} = S) -> + case orddict:find(Num, D) of + error -> + {error_unwritten, S}; + {ok, Proj} -> + {{ok, Proj}, S} + end. + +do_proj_get_latest_num(#state{proj_store=D} = S) -> + case lists:sort(orddict:to_list(D)) of + [] -> + {error_unwritten, S}; + L -> + {Num, _Proj} = lists:last(L), + {{ok, Num}, S} + end. diff --git a/prototype/poc-machi/test/machi_flu0_test.erl b/prototype/poc-machi/test/machi_flu0_test.erl index 2691a3c..09d4d1e 100644 --- a/prototype/poc-machi/test/machi_flu0_test.erl +++ b/prototype/poc-machi/test/machi_flu0_test.erl @@ -61,6 +61,21 @@ concuerror4_test() -> ok = machi_flu0:stop(F1), ok. +proj_store_test() -> + {ok, F1} = machi_flu0:start_link("one"), + + error_unwritten = machi_flu0:proj_get_latest_num(F1), + error_unwritten = machi_flu0:proj_read_latest(F1), + + Proj1 = whatever1, + ok = machi_flu0:proj_write(F1, 1, Proj1), + error_written = machi_flu0:proj_write(F1, 1, Proj1), + {ok, Proj1} = machi_flu0:proj_read(F1, 1), + {ok, 1} = machi_flu0:proj_get_latest_num(F1), + {ok, Proj1} = machi_flu0:proj_read_latest(F1), + + ok = machi_flu0:stop(F1), + ok. -endif. -endif.