diff --git a/rebar.config b/rebar.config index 5ff7129..4936f36 100644 --- a/rebar.config +++ b/rebar.config @@ -3,5 +3,6 @@ {deps, [ {plain_fsm, "1.1.*", {git, "git://github.com/uwiger/plain_fsm", {branch, "master"}}}, - {ebloom, "1.0.*", {git, "git://github.com/basho/ebloom.git", {branch, "master"}}} + {ebloom, "1.0.*", {git, "git://github.com/basho/ebloom.git", {branch, "master"}}}, + {basho_bench, ".*", {git, "git://github.com/basho/basho_bench.git", {branch, "master"}}} ]}. diff --git a/src/basho_bench_driver_fractal_btree.erl b/src/basho_bench_driver_fractal_btree.erl new file mode 100644 index 0000000..34db63c --- /dev/null +++ b/src/basho_bench_driver_fractal_btree.erl @@ -0,0 +1,75 @@ +-module(basho_bench_driver_fractal_btree). + +-record(state, { tree, + filename, + flags, + sync_interval, + last_sync }). + +-export([new/1, + run/4]). + +-include_lib("basho_bench/include/basho_bench.hrl"). + + +%% ==================================================================== +%% API +%% ==================================================================== + +new(_Id) -> + %% Make sure bitcask is available + case code:which(fractal_btree) of + non_existing -> + ?FAIL_MSG("~s requires fractal_btree to be available on code path.\n", + [?MODULE]); + _ -> + ok + end, + + %% Get the target directory + Dir = basho_bench_config:get(fractal_btree_dir, "."), + Filename = filename:join(Dir, "test.frac"), + + %% Look for sync interval config + case basho_bench_config:get(fractal_btree_sync_interval, infinity) of + Value when is_integer(Value) -> + SyncInterval = Value; + infinity -> + SyncInterval = infinity + end, + + %% Get any bitcask flags + case fractal_btree:open(Filename) of + {error, Reason} -> + ?FAIL_MSG("Failed to open fractal btree in ~s: ~p\n", [Filename, Reason]); + {ok, FBTree} -> + {ok, #state { tree = FBTree, + filename = Filename, + sync_interval = SyncInterval, + last_sync = os:timestamp() }} + end. + +run(get, KeyGen, _ValueGen, State) -> + case fractal_btree:lookup(State#state.tree, KeyGen()) of + {ok, _Value} -> + {ok, State}; + notfound -> + {ok, State}; + {error, Reason} -> + {error, Reason} + end; +run(put, KeyGen, ValueGen, State) -> + case fractal_btree:put(State#state.tree, KeyGen(), ValueGen()) of + ok -> + {ok, State}; + {error, Reason} -> + {error, Reason} + end; +run(delete, KeyGen, _ValueGen, State) -> + case fractal_btree:delete(State#state.tree, KeyGen()) of + ok -> + {ok, State}; + {error, Reason} -> + {error, Reason} + end. + diff --git a/src/fractal_btree.erl b/src/fractal_btree.erl index dc8253e..62e0014 100644 --- a/src/fractal_btree.erl +++ b/src/fractal_btree.erl @@ -147,7 +147,7 @@ do_put(Key, Value, State=#state{ nursery=Tree }) -> flush_nursery(State=#state{nursery=Tree, top=Top}) -> TreeSize = gb_trees:size( Tree ), if TreeSize > 0 -> - error_logger:info_msg("flushing to top=~p, alive=~p~n", [Top, erlang:is_process_alive(Top)]), +% error_logger:info_msg("flushing to top=~p, alive=~p~n", [Top, erlang:is_process_alive(Top)]), FileName = filename:join(State#state.dir, "nursery.data"), {ok, BT} = fractal_btree_writer:open(FileName, (1 bsl ?TOP_LEVEL)), lists:foreach( fun({Key2,Value2}) -> diff --git a/src/fractal_btree_bbench.config b/src/fractal_btree_bbench.config new file mode 100644 index 0000000..3399ee8 --- /dev/null +++ b/src/fractal_btree_bbench.config @@ -0,0 +1,26 @@ + +{mode, max}. + +{duration, 1}. + +{concurrent, 1}. + +{driver, basho_bench_driver_fractal_btree}. + +{key_generator, {int_to_bin,{uniform_int, 5000000}}}. + +{value_generator, {fixed_bin, 10000}}. + +{operations, [{get, 1}, {put, 1}]}. + +%% the second element in the list below (e.g., "../../public/bitcask") must point to +%% the relevant directory of a fractal_btree installation +{code_paths, ["deps/stats", + "/Users/krab/Projects/fractal_btree/ebin", + "/Users/krab/Projects/fractal_btree/deps/plain_fsm/ebin", + "/Users/krab/Projects/fractal_btree/deps/ebloom/ebin" + ]}. + +{bitcask_dir, "/tmp/fractal_btree.bench"}. + +{bitcask_flags, [o_sync]}. diff --git a/src/fractal_btree_level.erl b/src/fractal_btree_level.erl index 6054835..4c07fb7 100644 --- a/src/fractal_btree_level.erl +++ b/src/fractal_btree_level.erl @@ -79,7 +79,7 @@ reply({PID,Ref}, Reply) -> initialize(State) -> - error_logger:info_msg("in ~p level=~p~n", [self(), State]), +% error_logger:info_msg("in ~p level=~p~n", [self(), State]), AFileName = filename("A",State), BFileName = filename("B",State), @@ -126,7 +126,6 @@ check_begin_merge_then_loop(State) -> main_loop(State = #state{ next=Next }) -> Parent = plain_fsm:info(parent), - error_logger:info_msg("in main_loop~n", []), receive ?REQ(From, {lookup, Key})=Req -> case do_lookup(Key, [State#state.b, State#state.b, Next]) of @@ -249,7 +248,7 @@ begin_merge(State) -> {ok, OutCount} = fractal_btree_merger:merge(AFileName, BFileName, XFileName, State#state.level + 1), - error_logger:info_msg("merge done ~p,~p -> ~p~n", [AFileName, BFileName, XFileName]), +% error_logger:info_msg("merge done ~p,~p -> ~p~n", [AFileName, BFileName, XFileName]), Owner ! {merge_done, OutCount, XFileName} end), diff --git a/src/fractal_btree_writer.erl b/src/fractal_btree_writer.erl index 0b85d6a..3e21eac 100644 --- a/src/fractal_btree_writer.erl +++ b/src/fractal_btree_writer.erl @@ -54,13 +54,19 @@ init([Name,Size]) -> % io:format("got name: ~p~n", [Name]), - {ok, IdxFile} = file:open( fractal_btree_util:index_file_name(Name), - [raw, exclusive, write, delayed_write]), - {ok, BloomFilter} = ebloom:new(erlang:min(Size,16#ffffffff), 0.01, 123), - {ok, #state{ name=Name, - index_file_pos=0, index_file=IdxFile, - bloom = BloomFilter - }}. + case file:open( fractal_btree_util:index_file_name(Name), + [raw, exclusive, write, delayed_write]) of + {ok, IdxFile} -> + {ok, BloomFilter} = ebloom:new(erlang:min(Size,16#ffffffff), 0.01, 123), + {ok, #state{ name=Name, + index_file_pos=0, index_file=IdxFile, + bloom = BloomFilter + }}; + {error, _}=Error -> + error_logger:error_msg("fractal_btree_writer cannot open ~p: ~p~n", [Name, Error]), + {stop, Error} + end. + handle_cast({add, Key, Data}, State) when is_binary(Key), is_binary(Data) -> {ok, State2} = add_record(0, Key, Data, State),