]> git.ipfire.org Git - thirdparty/squid.git/blame - src/FadingCounter.cc
Author: Alex Rousskov
[thirdparty/squid.git] / src / FadingCounter.cc
CommitLineData
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
10FadingCounter::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
18void FadingCounter::clear()
19{
20 for (int i = 0; i < precision; ++i)
21 counters[i] = 0;
22 lastTime = current_dtime;
23 total = 0;
24}
25
26void 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
35int 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}