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(),