| #include "average.hpp" |
| |
| #include <cassert> |
| |
| std::optional<Average::averageValue> |
| Average::getAverageValue(const Average::averageKey& sensorKey) const |
| { |
| const auto it = _previousAverageMap.find(sensorKey); |
| if (it == _previousAverageMap.end()) |
| { |
| return {}; |
| } |
| |
| return std::optional(it->second); |
| } |
| |
| void Average::setAverageValue(const Average::averageKey& sensorKey, |
| const Average::averageValue& sensorValue) |
| { |
| _previousAverageMap[sensorKey] = sensorValue; |
| } |
| |
| std::optional<int64_t> Average::calcAverage(int64_t preAverage, |
| int64_t preInterval, |
| int64_t curAverage, |
| int64_t curInterval) |
| { |
| int64_t value = 0; |
| // Estimate that the interval will overflow about 292471 |
| // years after it starts counting, so consider it won't |
| // overflow |
| int64_t delta = curInterval - preInterval; |
| |
| assert(delta >= 0); |
| // 0 means the delta interval is too short, the value of |
| // power*_average_interval is not changed yet |
| if (delta == 0) |
| { |
| return {}; |
| } |
| // Change formula (a2*i2-a1*i1)/(i2-i1) to be the |
| // following formula, to avoid multiplication overflow. |
| // (a2*i2-a1*i1)/(i2-i1) = |
| // (a2*(i1+delta)-a1*i1)/delta = |
| // (a2-a1)(i1/delta)+a2 |
| value = (curAverage - preAverage) * |
| (static_cast<double>(preInterval) / delta) + |
| curAverage; |
| |
| return value; |
| } |