2 // FrequencyStatistics.cs
4 // Copyright (C) 2004 Novell, Inc.
8 // Permission is hereby granted, free of charge, to any person obtaining a
9 // copy of this software and associated documentation files (the "Software"),
10 // to deal in the Software without restriction, including without limitation
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 // and/or sell copies of the Software, and to permit persons to whom the
13 // Software is furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 // DEALINGS IN THE SOFTWARE.
28 using System
.Collections
;
29 using System
.Threading
;
31 namespace Beagle
.Util
{
33 public class FrequencyStatistics
{
35 // In this code, all time spans represented
36 // by doubles are measured in seconds.
38 // OK, this is crack. We fix a very large
39 // constant that is returned as the gap before
40 // the second event comes in. This is a hack
41 // that lets us pretty much ignore the special
42 // case of the initial state in our backoff code.
43 private const double first_gap
= 1.0e+8;
45 // decay is between 0.0 and 1.0.
46 // A lower number implies a longer memory.
47 private const double decay
= 0.317732; // a magic constant
49 private int count
= 0;
50 private double expma_gap
;
51 private DateTime previous_time
;
57 public double TimeSinceLastEvent
{
62 return (DateTime
.Now
- previous_time
).TotalSeconds
;
66 public double EstimatedFrequency
{
71 // expma_gap will always be > 0
72 // It might be very small, though.
77 public double ImpliedFrequency
{
79 return ComputeExpMaGap (DateTime
.Now
, expma_gap
);
83 // How many seconds would be have to be idle for our exmpa
84 // frequency to reach the required level.
85 public double TimeToReachFrequency (double target_frequency
)
87 if (target_frequency
< 0.001)
90 double target_gap
= 1 / target_frequency
;
92 if (count
< 2 || (target_gap
< expma_gap
))
95 // Compute the size of gap that would get us to the
98 t
= (target_gap
- (1 - decay
) * expma_gap
) / decay
;
100 // Adjust by the amount of time that has actually passed.
101 t
-= (DateTime
.Now
- previous_time
).TotalSeconds
;
103 return Math
.Max (t
, 0);
106 private double ComputeExpMaGap (DateTime now
, double prev
)
111 double gap
= (now
- previous_time
).TotalSeconds
;
116 return decay
* gap
+ (1 - decay
) * prev
;
119 public void AddEvent ()
121 DateTime now
= DateTime
.Now
;
122 expma_gap
= ComputeExpMaGap (now
, expma_gap
);