1 %%%-------------------------------------------------------------------
2 %%% File : etorrent_rate.erl
3 %%% Author : Jesper Louis Andersen <>
4 %%% Description : Library of rate calculation code.
6 %%% Created : 10 Jul 2008 by Jesper Louis Andersen <>
7 %%%-------------------------------------------------------------------
8 -module(etorrent_rate
).
11 -export([init
/1, update
/2, now_secs
/0]).
13 -include("etorrent_rate.hrl").
15 -define(MAX_RATE_PERIOD
, 20).
17 %%====================================================================
19 %%====================================================================
20 %%--------------------------------------------------------------------
22 %% Args: Fudge ::= integer() - The fudge skew to start out with
23 %% Description: Return an initialized rate tuple.
24 %%--------------------------------------------------------------------
27 #peer_rate
{ next_expected
= T
+ Fudge
,
29 rate_since
= T
- Fudge
}.
31 %%--------------------------------------------------------------------
33 %% Args: Amount ::= integer() - Number of bytes that arrived
34 %% Rate ::= double() - Current rate
35 %% Total ::= integer() - Total amount of bytes downloaded
36 %% NextExpected ::= time() - When is the next update expected
37 %% Last ::= time() - When was the last update
38 %% RateSince ::= time() - Point in time where the rate has its
40 %% Description: Update the rate by Amount.
41 %%--------------------------------------------------------------------
42 update(#peer_rate
{rate
= Rate
,
44 next_expected
= NextExpected
,
46 rate_since
= RateSince
} = RT
, Amount
) when is_integer(Amount
) ->
48 case T
< NextExpected andalso Amount
=:= 0 of
50 %% We got 0 bytes, but we did not expect them yet, so just
51 %% return the current tuple (simplification candidate)
54 %% New rate: Timeslot between Last and RateSince contributes
55 %% with the old rate. Then we add the new Amount and calc.
56 %% the rate for the interval [T, RateSince].
57 R
= (Rate
* (Last
- RateSince
) + Amount
) / (T
- RateSince
),
58 #peer_rate
{ rate
= R
, %% New Rate
59 total
= Total
+ Amount
,
60 %% We expect the next data-block at the minimum of 5 secs or
61 %% when Amount bytes has been fetched at the current rate.
63 T
+ lists:min([5, Amount
/ lists:max([R
, 0.0001])]),
65 %% RateSince is manipulated so it does not go beyond
67 rate_since
= lists:max([RateSince
, T
- ?MAX_RATE_PERIOD
])}
70 %%====================================================================
72 %%====================================================================
74 calendar:datetime_to_gregorian_seconds(
75 calendar:local_time()).