Merge pull request #47 from basho/jdb-faster-slide-eunit-fixes-squashed
Improve performance of slide histogram
diff --git a/src/folsom_sample_slide.erl b/src/folsom_sample_slide.erl
index 4b13a36..631d821 100644
--- a/src/folsom_sample_slide.erl
+++ b/src/folsom_sample_slide.erl
@@ -33,6 +33,8 @@
-include("folsom.hrl").
+-define(WIDTH, 16). %% Keep this a power of two
+
new(Size) ->
Sample = #slide{window = Size},
Pid = folsom_sample_slide_sup:start_slide_server(?MODULE, Sample#slide.reservoir, Sample#slide.window),
@@ -40,16 +42,18 @@
update(#slide{reservoir = Reservoir} = Sample, Value) ->
Moment = moment(),
- ets:insert(Reservoir, {Moment, Value}),
+ X = erlang:system_info(scheduler_id),
+ Rnd = X band (?WIDTH-1),
+ ets:insert(Reservoir, {{Moment, Rnd}, Value}),
Sample.
get_values(#slide{window = Window, reservoir = Reservoir}) ->
Oldest = moment() - Window,
- ets:select(Reservoir, [{{'$1','$2'},[{'>=', '$1', Oldest}],['$2']}]).
+ ets:select(Reservoir, [{{{'$1','_'},'$2'},[{'>=', '$1', Oldest}],['$2']}]).
moment() ->
folsom_utils:now_epoch().
trim(Reservoir, Window) ->
Oldest = moment() - Window,
- ets:select_delete(Reservoir, [{{'$1','_'},[{'<', '$1', Oldest}],['true']}]).
+ ets:select_delete(Reservoir, [{{{'$1','_'},'_'},[{'<', '$1', Oldest}],['true']}]).
diff --git a/test/folsom_sample_slide_test.erl b/test/folsom_sample_slide_test.erl
index b1a0fd5..fa31a0e 100644
--- a/test/folsom_sample_slide_test.erl
+++ b/test/folsom_sample_slide_test.erl
@@ -100,6 +100,6 @@
Tab = lists:sort(ets:tab2list(Slide#slide.reservoir)),
{Ks, Vs} = lists:unzip(Tab),
ExpectedVs = lists:sort(lists:flatten([lists:duplicate(10, N) || N <- Moments])),
- Keys = lists:usort(Ks),
- ?assertEqual(Moments, Keys),
+ StrippedKeys = lists:usort([X || {X, _} <- Ks]),
+ ?assertEqual(Moments, StrippedKeys),
?assertEqual(ExpectedVs, lists:sort(Vs)).
diff --git a/test/slide_statem_eqc.erl b/test/slide_statem_eqc.erl
index a3fddd9..a8857fd 100644
--- a/test/slide_statem_eqc.erl
+++ b/test/slide_statem_eqc.erl
@@ -36,7 +36,6 @@
--define(NUMTESTS, 200).
-define(QC_OUT(P),
eqc:on_output(fun(Str, Args) ->
io:format(user, Str, Args) end, P)).
@@ -95,7 +94,8 @@
end;
postcondition(#state{values=Values, sample=Sample, moment=Moment}, {call, ?MODULE, trim, _}, _TrimCnt) ->
%% check that values and the actual table contents are the same after a trim
- Table = ets:tab2list(Sample#slide.reservoir),
+ Table0 = ets:tab2list(Sample#slide.reservoir),
+ Table = [{X, Y} || {{X, _}, Y} <- Table0],
Model = lists:sort(trim(Values, Moment, ?WINDOW)),
case Model == lists:sort(Table) of
true ->
@@ -107,9 +107,13 @@
true.
prop_window_test_() ->
- {setup, fun() -> ok end, fun(_X) -> (catch meck:unload(folsom_utils)), folsom:stop() end,
- fun(_X) ->
- ?_assert(eqc:quickcheck(eqc:numtests(?NUMTESTS, ?QC_OUT(prop_window())))) end}.
+ Seconds = 10,
+ {setup,
+ fun() -> ok end,
+ fun(_X) -> (catch meck:unload(folsom_utils)), folsom:stop() end,
+ [{"QuickCheck Test",
+ {timeout, Seconds*2, fun() -> true = eqc:quickcheck(eqc:testing_time(Seconds, ?QC_OUT(prop_window()))) end
+ }}]}.
prop_window() ->
folsom:start(),