blob: 77b24139923914429a8f57c457ef75e7bc3271e5 [file] [log] [blame]
%%%
%%% Copyright 2011, Boundary
%%%
%%% Licensed 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.
%%%
%%%-------------------------------------------------------------------
%%% File: folsom_ewma.erl
%%% @author joe williams <j@boundary.com>
%%% @doc
%%% based on https://github.com/codahale/metrics/blob/development/src/main/java/com/yammer/metrics/stats/EWMA.java
%%% references:
%%% http://www.teamquest.com/pdfs/whitepaper/ldavg1.pdf
%%% http://www.teamquest.com/pdfs/whitepaper/ldavg2.pdf
%%% @end
%%%-----------------------------------------------------------------
-module(folsom_ewma).
-define(M1_ALPHA, 1 - math:exp(-5 / 60.0)).
-define(M5_ALPHA, 1 - math:exp(-5 / 60.0 / 5)).
-define(M15_ALPHA, 1 - math:exp(-5 / 60.0 / 15)).
-define(D1_ALPHA, 1 - math:exp(-5 / 60.0 / 1440)).
-record(ewma, {
alpha,
interval = 5, % seconds
initialized = false,
rate = 0,
total = 0
}).
-export([update/2,
new/2,
rate/1,
tick/1,
one_minute_ewma/0,
five_minute_ewma/0,
fifteen_minute_ewma/0,
one_day_ewma/0]).
% API
one_minute_ewma() ->
new(?M1_ALPHA, 5).
five_minute_ewma() ->
new(?M5_ALPHA, 5).
fifteen_minute_ewma() ->
new(?M15_ALPHA, 5).
one_day_ewma() ->
new(?D1_ALPHA, 5).
new(Alpha, Interval) ->
#ewma{alpha = Alpha, interval = Interval}.
update(#ewma{total = Total} = EWMA, Value) ->
EWMA#ewma{total = Total + Value}.
tick(#ewma{total = Total, rate = Rate, initialized = Init, interval = Interval, alpha = Alpha} = EWMA) ->
InstantRate = Total / Interval,
Rate1 = rate_calc(Init, Alpha, Rate, InstantRate),
EWMA#ewma{rate = Rate1, initialized = true, total = 0}.
rate(#ewma{rate = Rate}) ->
Rate.
% Internal API
rate_calc(true, Alpha, Rate, InstantRate) ->
Rate1 = Rate + (Alpha * (InstantRate - Rate)),
Rate1;
rate_calc(false, _, _, InstantRate) ->
InstantRate.