]>
Commit | Line | Data |
---|---|---|
bbc27441 | 1 | /* |
bde978a6 | 2 | * Copyright (C) 1996-2015 The Squid Software Foundation and contributors |
bbc27441 AJ |
3 | * |
4 | * Squid software is distributed under GPLv2+ license and includes | |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
7 | */ | |
8 | ||
582c2af2 | 9 | #include "squid.h" |
8277060a | 10 | #include "base/TextException.h" |
8277060a | 11 | #include "FadingCounter.h" |
602d9612 | 12 | #include "SquidTime.h" |
8277060a | 13 | |
074d6a40 | 14 | #include <cmath> |
582c2af2 | 15 | |
8277060a | 16 | FadingCounter::FadingCounter(): horizon(-1), precision(10), delta(-1), |
f53969cc | 17 | lastTime(0), total(0) |
8277060a CT |
18 | { |
19 | counters.reserve(precision); | |
20 | while (counters.size() < static_cast<unsigned int>(precision)) | |
21 | counters.push_back(0); | |
22 | } | |
23 | ||
24 | void FadingCounter::clear() | |
25 | { | |
26 | for (int i = 0; i < precision; ++i) | |
27 | counters[i] = 0; | |
28 | lastTime = current_dtime; | |
29 | total = 0; | |
30 | } | |
31 | ||
32 | void FadingCounter::configure(double newHorizon) | |
33 | { | |
34 | if (fabs(newHorizon - horizon) >= 1e-3) { // diff exceeds one millisecond | |
35 | clear(); // for simplicity | |
36 | horizon = newHorizon; | |
37 | delta = horizon / precision; // may become negative or zero | |
38 | } | |
39 | } | |
40 | ||
41 | int FadingCounter::count(int howMany) | |
42 | { | |
43 | Must(howMany >= 0); | |
44 | ||
45 | if (delta < 0) | |
46 | return total += howMany; // forget nothing | |
47 | ||
48 | if (horizon < 1e-3) // (e.g., zero) | |
49 | return howMany; // remember nothing | |
50 | ||
51 | const double deltas = (current_dtime - lastTime) / delta; | |
52 | if (deltas >= precision || current_dtime < lastTime) { | |
53 | clear(); // forget all values | |
54 | } else { | |
55 | // forget stale values, if any | |
56 | // fmod() or "current_dtime/delta" will overflow int for small deltas | |
57 | const int lastSlot = static_cast<int>(fmod(lastTime, horizon) / delta); | |
58 | const int staleSlots = static_cast<int>(deltas); | |
59 | for (int i = 0, s = lastSlot + 1; i < staleSlots; ++i, ++s) { | |
60 | const int idx = s % precision; | |
61 | total -= counters[idx]; | |
62 | counters[idx] = 0; | |
63 | Must(total >= 0); | |
64 | } | |
65 | } | |
66 | ||
67 | // apply new information | |
68 | lastTime = current_dtime; | |
69 | const int curSlot = static_cast<int>(fmod(lastTime, horizon) / delta); | |
70 | counters[curSlot % precision] += howMany; | |
71 | total += howMany; | |
72 | Must(total >= 0); | |
73 | ||
74 | return total; | |
75 | } | |
f53969cc | 76 |