]>
Commit | Line | Data |
---|---|---|
8277060a CT |
1 | /* |
2 | * $Id$ | |
3 | */ | |
4 | ||
5 | #include "squid.h" | |
6 | #include "base/TextException.h" | |
7 | #include "SquidTime.h" | |
8 | #include "FadingCounter.h" | |
9 | ||
10 | FadingCounter::FadingCounter(): horizon(-1), precision(10), delta(-1), | |
11 | lastTime(0), total(0) | |
12 | { | |
13 | counters.reserve(precision); | |
14 | while (counters.size() < static_cast<unsigned int>(precision)) | |
15 | counters.push_back(0); | |
16 | } | |
17 | ||
18 | void FadingCounter::clear() | |
19 | { | |
20 | for (int i = 0; i < precision; ++i) | |
21 | counters[i] = 0; | |
22 | lastTime = current_dtime; | |
23 | total = 0; | |
24 | } | |
25 | ||
26 | void FadingCounter::configure(double newHorizon) | |
27 | { | |
28 | if (fabs(newHorizon - horizon) >= 1e-3) { // diff exceeds one millisecond | |
29 | clear(); // for simplicity | |
30 | horizon = newHorizon; | |
31 | delta = horizon / precision; // may become negative or zero | |
32 | } | |
33 | } | |
34 | ||
35 | int FadingCounter::count(int howMany) | |
36 | { | |
37 | Must(howMany >= 0); | |
38 | ||
39 | if (delta < 0) | |
40 | return total += howMany; // forget nothing | |
41 | ||
42 | if (horizon < 1e-3) // (e.g., zero) | |
43 | return howMany; // remember nothing | |
44 | ||
45 | const double deltas = (current_dtime - lastTime) / delta; | |
46 | if (deltas >= precision || current_dtime < lastTime) { | |
47 | clear(); // forget all values | |
48 | } else { | |
49 | // forget stale values, if any | |
50 | // fmod() or "current_dtime/delta" will overflow int for small deltas | |
51 | const int lastSlot = static_cast<int>(fmod(lastTime, horizon) / delta); | |
52 | const int staleSlots = static_cast<int>(deltas); | |
53 | for (int i = 0, s = lastSlot + 1; i < staleSlots; ++i, ++s) { | |
54 | const int idx = s % precision; | |
55 | total -= counters[idx]; | |
56 | counters[idx] = 0; | |
57 | Must(total >= 0); | |
58 | } | |
59 | } | |
60 | ||
61 | // apply new information | |
62 | lastTime = current_dtime; | |
63 | const int curSlot = static_cast<int>(fmod(lastTime, horizon) / delta); | |
64 | counters[curSlot % precision] += howMany; | |
65 | total += howMany; | |
66 | Must(total >= 0); | |
67 | ||
68 | return total; | |
69 | } |