root/hydranode/hnbase/speedmeter.cpp

Revision 2613, 3.2 kB (checked in by madcat, 3 years ago)

Copyright notice update for 2006.

Line 
1 /*
2  *  Copyright (C) 2004-2006 Alo Sarv <madcat_@users.sourceforge.net>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19 /**
20  * \file speedmeter.cpp      Implementation of SpeedMeter class
21  */
22
23 #include <hnbase/speedmeter.h>
24
25 /*
26  * Original idea and implementation credits go to Xaignar.
27  *
28  * There are two key variables in this speedmeter implementation - history size,
29  * and resolution.
30  *
31  * Resolution defines how large is the allowed error, e.g. in case of 100ms
32  * resolution, getSpeed() accuracy is 100ms in best-case scenario.
33  *
34  * History size defines how large amount of history data should be gathered.
35  * The getSpeed() returns the sum of all history values, plus the m_recent
36  * value, which keeps the last (not-yet-in-history) value. This results in
37  * possible fluctuation of speeds at most @resolution amount.
38  *
39  * Gaps longer than histSize - 1 would result in a queue of zeroes, so to avoid
40  * needless list manipulation, we can simply clear the list if the gap becomes
41  * larger than histSize - 1 (which gives the same result, e.g. 0).
42  *
43  * If the gap is more than a single @resolution interval, then the first
44  * @resolution interval will contain the last "recent" value, whereas the next
45  * intervals will be zero, as no adds occoured for them.
46  *
47  * Total of histSize - 1 entries are kept, which together with the amount stored
48  * in m_recent give a timespan of histSize * resolution.
49  */
50
51 const uint64_t *SpeedMeter::m_ticker = 0;
52
53 SpeedMeter::SpeedMeter() : m_recent(), m_current(), m_total(), m_lastReset(),
54 m_histSize(10), m_res(100) {
55 }
56
57 SpeedMeter::SpeedMeter(uint32_t histSize, uint32_t resolution) : m_recent(),
58 m_current(), m_total(), m_lastReset(), m_histSize(histSize), m_res(resolution) {
59 }
60
61 SpeedMeter& SpeedMeter::operator+=(uint32_t amount) {
62         uint64_t curTick = m_ticker ? *m_ticker : Utils::getTick();
63
64         if (m_lastReset + (m_histSize - 1) * m_res < curTick) {
65                 m_history.clear();
66                 m_recent     = amount;
67                 m_lastReset += m_res * ((curTick - m_lastReset) / m_res);
68                 m_current    = amount;
69         } else if (m_lastReset + m_res < curTick) {
70                 do {
71                         m_history.push_back(m_recent);
72                         m_lastReset += m_res;
73                         m_recent     = 0;
74                 } while (m_lastReset + m_res < curTick);
75                 m_recent   = amount;
76                 m_current += amount;
77                 while (m_history.size() > m_histSize - 1) {
78                         m_current -= m_history.front();
79                         m_history.pop_front();
80                 }
81         } else {
82                 m_recent  += amount;
83                 m_current += amount;
84         }
85         m_total += amount;
86         return *this;
87 }
88
89 void SpeedMeter::setTicker(const uint64_t &ticker) {
90         m_ticker = &ticker;
91 }
92
93 void SpeedMeter::unsetTicker() {
94         m_ticker = 0;
95 }
Note: See TracBrowser for help on using the browser.