Skip to content

Commit

Permalink
Add modulo-factoring-formatting key generator.
Browse files Browse the repository at this point in the history
  • Loading branch information
seancribbs committed Feb 11, 2011
1 parent 59bdd00 commit 7e6b288
Showing 1 changed file with 36 additions and 20 deletions.
56 changes: 36 additions & 20 deletions src/basho_bench_keygen.erl
Expand Up @@ -22,7 +22,8 @@
-module(basho_bench_keygen).

-export([new/2,
dimension/1]).
dimension/1,
mod_factor/2]).

-include("basho_bench.hrl").

Expand Down Expand Up @@ -66,11 +67,16 @@ new({function, Module, Function, Args}, Id) ->
_Error ->
?FAIL_MSG("Could not find keygen function: ~p:~p\n", [Module, Function])
end;
new({modulo_format, InputGen, Format, Pieces}, Id) ->
Gen = new(InputGen, Id),
fun() -> lists:flatten(io_lib:format(Format, mod_factor(Gen(), Pieces))) end;
new(Other, _Id) ->
?FAIL_MSG("Unsupported key generator requested: ~p\n", [Other]).

dimension({Converter, InputGen}) when Converter == int_to_str orelse Converter == int_to_bin ->
dimension(InputGen);
dimension({modulo_format, InputGen, _, _}) ->
dimension(InputGen);
dimension({sequential_int, MaxKey}) ->
MaxKey;
dimension({partitioned_sequential_int, MaxKey}) ->
Expand Down Expand Up @@ -98,22 +104,32 @@ pareto(Mean, Shape) ->


sequential_int_generator(Ref, MaxValue) ->
%% A bit of evil here. We want to generate numbers in sequence and stop
%% at MaxKey. This means we need state in our anonymous function. Use the process
%% dictionary to keep track of where we are.
case erlang:get({sigen, Ref}) of
undefined ->
erlang:put({sigen, Ref}, 1),
0;
MaxValue ->
throw({stop, empty_keygen});
Value ->
case Value rem 5000 of
0 ->
?DEBUG("sequential_int_gen: ~p (~w%)\n", [Value, trunc(100 * (Value / MaxValue))]);
_ ->
ok
end,
erlang:put({sigen, Ref}, Value+1),
Value
end.
%% A bit of evil here. We want to generate numbers in sequence and stop
%% at MaxKey. This means we need state in our anonymous function. Use the process
%% dictionary to keep track of where we are.
case erlang:get({sigen, Ref}) of
undefined ->
erlang:put({sigen, Ref}, 1),
0;
MaxValue ->
throw({stop, empty_keygen});
Value ->
case Value rem 5000 of
0 ->
?DEBUG("sequential_int_gen: ~p (~w%)\n", [Value, trunc(100 * (Value / MaxValue))]);
_ ->
ok
end,
erlang:put({sigen, Ref}, Value+1),
Value
end.

% Factors a number into constituent pieces by progressively dividing
% it by the given numbers. All factors are one-based (rather than zero).
mod_factor(Value, Pieces) ->
mod_factor(Value, lists:reverse(Pieces), []).

mod_factor(_Value, [], Acc) ->
Acc;
mod_factor(Value, [Divisor|Rest], Acc) ->
mod_factor(Value div Divisor, Rest, [(Value rem Divisor)+1|Acc]).

0 comments on commit 7e6b288

Please sign in to comment.