Ha! Damn quick and easy to add tango_dt_map.erl
This commit is contained in:
parent
df53ec0a4e
commit
6caeaeb6b5
4 changed files with 106 additions and 2 deletions
|
@ -98,7 +98,7 @@ handle_call({cb_dirty_op, Op}, _From,
|
|||
handle_call({cb_pure_op, Op}, _From, #state{cb_mod=CallbackMod} = State) ->
|
||||
State2 = #state{i_state=I_State} = roll_log_forward(State),
|
||||
Reply = CallbackMod:do_pure_op(Op, I_State),
|
||||
{reply, {ok, Reply}, State2};
|
||||
{reply, Reply, State2};
|
||||
handle_call({stop}, _From, State) ->
|
||||
{stop, normal, ok, State};
|
||||
handle_call(_Request, _From, State) ->
|
||||
|
|
69
prototype/tango-prototype/src/tango_dt_map.erl
Normal file
69
prototype/tango-prototype/src/tango_dt_map.erl
Normal file
|
@ -0,0 +1,69 @@
|
|||
%% -------------------------------------------------------------------
|
||||
%%
|
||||
%% Copyright (c) 2014 Basho Technologies, Inc. All Rights Reserved.
|
||||
%%
|
||||
%% This file is provided to you under the Apache License,
|
||||
%% Version 2.0 (the "License"); you may not use this file
|
||||
%% except in compliance with the License. You may obtain
|
||||
%% a copy of the License at
|
||||
%%
|
||||
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||
%%
|
||||
%% Unless required by applicable law or agreed to in writing,
|
||||
%% software distributed under the License is distributed on an
|
||||
%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
%% KIND, either express or implied. See the License for the
|
||||
%% specific language governing permissions and limitations
|
||||
%% under the License.
|
||||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
-module(tango_dt_map).
|
||||
|
||||
-behaviour(tango_dt).
|
||||
|
||||
-export([start_link/4,
|
||||
set/3, get/2]).
|
||||
|
||||
%% Tango datatype callbacks
|
||||
-export([fresh/0,
|
||||
do_pure_op/2, do_dirty_op/6, play_log_mutate_i_state/3]).
|
||||
|
||||
-define(DICTMOD, dict).
|
||||
|
||||
-define(LONG_TIME, 30*1000).
|
||||
|
||||
start_link(PageSize, SequencerPid, Proj, StreamNum) ->
|
||||
gen_server:start_link(tango_dt,
|
||||
[PageSize, SequencerPid, Proj, ?MODULE, StreamNum],
|
||||
[]).
|
||||
|
||||
set(Pid, Key, Val) ->
|
||||
gen_server:call(Pid, {cb_dirty_op, {o_set, Key, Val}}, ?LONG_TIME).
|
||||
|
||||
get(Pid, Key) ->
|
||||
gen_server:call(Pid, {cb_pure_op, {o_get, Key}}, ?LONG_TIME).
|
||||
|
||||
|
||||
fresh() ->
|
||||
?DICTMOD:new().
|
||||
|
||||
do_pure_op({o_get, Key}, Dict) ->
|
||||
?DICTMOD:find(Key, Dict).
|
||||
|
||||
do_dirty_op({o_set, _Key, _Val}=Op,
|
||||
I_State, StreamNum, Proj0, PageSize, BackPs) ->
|
||||
Page = term_to_binary(Op),
|
||||
FullPage = tango:pack_v1([{StreamNum, BackPs}], Page, PageSize),
|
||||
{{ok, LPN}, Proj1} = corfurl_client:append_page(Proj0, FullPage,
|
||||
[StreamNum]),
|
||||
NewBackPs = tango:add_back_pointer(BackPs, LPN),
|
||||
{ok, I_State, Proj1, LPN, NewBackPs}.
|
||||
|
||||
play_log_mutate_i_state(Pages, _SideEffectsP, I_State) ->
|
||||
lists:foldl(fun({o_set, Key, Val}=_Op, Dict) ->
|
||||
?DICTMOD:store(Key, Val, Dict)
|
||||
end,
|
||||
I_State,
|
||||
[binary_to_term(Page) || Page <- Pages]).
|
||||
|
|
@ -47,7 +47,7 @@ fresh() ->
|
|||
undefined.
|
||||
|
||||
do_pure_op({o_get}, Register) ->
|
||||
Register.
|
||||
{ok, Register}.
|
||||
|
||||
do_dirty_op({o_set, _Val}=Op,
|
||||
I_State, StreamNum, Proj0, PageSize, BackPs) ->
|
||||
|
|
|
@ -193,5 +193,40 @@ tango_dt_register_int(PageSize, Seq, Proj) ->
|
|||
|
||||
ok.
|
||||
|
||||
tango_dt_map_test() ->
|
||||
ok = run_test("/tmp", "tango_dt_map",
|
||||
4096, 5*1024, 1, fun tango_dt_map_int/3).
|
||||
|
||||
tango_dt_map_int(PageSize, Seq, Proj) ->
|
||||
{ok, OID_Map} = tango_oid:start_link(PageSize, Seq, Proj),
|
||||
|
||||
{ok, Reg1Num} = tango_oid:new(OID_Map, "map1"),
|
||||
{ok, Reg1} = tango_dt_map:start_link(PageSize, Seq, Proj, Reg1Num),
|
||||
{ok, Reg2Num} = tango_oid:new(OID_Map, "map2"),
|
||||
{ok, Reg2} = tango_dt_map:start_link(PageSize, Seq, Proj, Reg2Num),
|
||||
|
||||
NumVals = 8,
|
||||
Vals = [lists:flatten(io_lib:format("version ~w", [X])) ||
|
||||
X <- lists:seq(1, NumVals)],
|
||||
Keys = ["key1", "key2"],
|
||||
[tango_dt_map:set(Reg, Key, Val) || Reg <- [Reg1, Reg2],
|
||||
Key <- Keys, Val <- Vals],
|
||||
LastVal = lists:last(Vals),
|
||||
[{ok, LastVal} = tango_dt_map:get(Reg1, Key) || Key <- Keys],
|
||||
[{ok, LastVal} = tango_dt_map:get(Reg2, Key) || Key <- Keys],
|
||||
|
||||
%% If we instantiate a new instance of an existing map, then
|
||||
%% a single get should show the most recent modification.
|
||||
{ok, Reg2b} = tango_dt_map:start_link(PageSize, Seq, Proj, Reg2Num),
|
||||
[{ok, LastVal} = tango_dt_map:get(Reg2b, Key) || Key <- Keys],
|
||||
%% If we update the "old" instance of a map, then the "new"
|
||||
%% instance should also see the update.
|
||||
NewVal = {"Heh", "a new value"},
|
||||
[ok = tango_dt_map:set(Reg2, Key, NewVal) || Key <- Keys],
|
||||
[{ok, NewVal} = tango_dt_map:get(Reg2b, Key) || Key <- Keys],
|
||||
[{ok, NewVal} = tango_dt_map:get(Reg2, Key) || Key <- Keys], % sanity
|
||||
|
||||
ok.
|
||||
|
||||
-endif. % not PULSE
|
||||
-endif. % TEST
|
||||
|
|
Loading…
Reference in a new issue