Browse Source

Reduce horizontal graphs resolution

Rewrite averaging code and reduce horizontal graphs resolution for
30 minutes and 6 hours graphs to decrease CPU usage.
adaptive-webui-19844
dzmat 6 years ago
parent
commit
23d924643f
  1. 93
      src/gui/properties/speedplotview.cpp
  2. 35
      src/gui/properties/speedplotview.h

93
src/gui/properties/speedplotview.cpp

@ -33,15 +33,67 @@ @@ -33,15 +33,67 @@
#include "base/global.h"
#include "base/utils/misc.h"
namespace
{
enum PeriodInSeconds
{
MIN1_SEC = 60,
MIN5_SEC = 5 * 60,
MIN30_SEC = 30 * 60,
HOUR6_SEC = 6 * 60 * 60
};
const int MIN5_BUF_SIZE = 5 * 60;
const int MIN30_BUF_SIZE = 5 * 60;
const int HOUR6_BUF_SIZE = 5 * 60;
const int DIVIDER_30MIN = MIN30_SEC / MIN30_BUF_SIZE;
const int DIVIDER_6HOUR = HOUR6_SEC / HOUR6_BUF_SIZE;
}
SpeedPlotView::Averager::Averager(int divider, boost::circular_buffer<PointData> &sink)
: m_divider(divider)
, m_sink(sink)
, m_counter(0)
, m_accumulator {}
{
}
void SpeedPlotView::Averager::push(const PointData &pointData)
{
// Accumulator overflow will be hit in worst case on longest used averaging span,
// defined by divider value. Maximum divider is DIVIDER_6HOUR = 72
// Using int32 for accumulator we get overflow when transfer speed reaches 2^31/72 ~~ 28.4 MBytes/s.
// With quint64 this speed limit is 2^64/72 ~~ 228 PBytes/s.
// This speed is inaccessible to an ordinary user.
m_accumulator.x += pointData.x;
for (int id = UP; id < NB_GRAPHS; ++id)
m_accumulator.y[id] += pointData.y[id];
m_counter = (m_counter + 1) % m_divider;
if (m_counter != 0)
return; // still accumulating
// it is time final averaging calculations
for (int id = UP; id < NB_GRAPHS; ++id)
m_accumulator.y[id] /= m_divider;
m_accumulator.x /= m_divider;
// now flush out averaged data
m_sink.push_back(m_accumulator);
m_accumulator = {};
}
bool SpeedPlotView::Averager::isReady() const
{
return m_counter == 0;
}
SpeedPlotView::SpeedPlotView(QWidget *parent)
: QGraphicsView(parent)
, m_data5Min(MIN5_BUF_SIZE)
, m_data30Min(MIN30_BUF_SIZE)
, m_data6Hour(HOUR6_BUF_SIZE)
, m_averager30Min(DIVIDER_30MIN, m_data30Min)
, m_averager6Hour(DIVIDER_6HOUR, m_data6Hour)
, m_period(MIN5)
, m_viewablePointsCount(MIN5_SEC)
, m_counter30Min(-1)
, m_counter6Hour(-1)
{
QPen greenPen;
greenPen.setWidthF(1.5);
@ -80,30 +132,11 @@ void SpeedPlotView::setGraphEnable(GraphID id, bool enable) @@ -80,30 +132,11 @@ void SpeedPlotView::setGraphEnable(GraphID id, bool enable)
viewport()->update();
}
void SpeedPlotView::pushPoint(SpeedPlotView::PointData point)
void SpeedPlotView::pushPoint(const SpeedPlotView::PointData &point)
{
m_counter30Min = (m_counter30Min + 1) % 3;
m_counter6Hour = (m_counter6Hour + 1) % 18;
m_data5Min.push_back(point);
if (m_counter30Min == 0) {
m_data30Min.push_back(point);
}
else {
m_data30Min.back().x = (m_data30Min.back().x * m_counter30Min + point.x) / (m_counter30Min + 1);
for (int id = UP; id < NB_GRAPHS; ++id)
m_data30Min.back().y[id] = (m_data30Min.back().y[id] * m_counter30Min + point.y[id]) / (m_counter30Min + 1);
}
if (m_counter6Hour == 0) {
m_data6Hour.push_back(point);
}
else {
m_data6Hour.back().x = (m_data6Hour.back().x * m_counter6Hour + point.x) / (m_counter6Hour + 1);
for (int id = UP; id < NB_GRAPHS; ++id)
m_data6Hour.back().y[id] = (m_data6Hour.back().y[id] * m_counter6Hour + point.y[id]) / (m_counter6Hour + 1);
}
m_averager30Min.push(point);
m_averager6Hour.push(point);
}
void SpeedPlotView::setViewableLastPoints(TimePeriod period)
@ -132,8 +165,8 @@ void SpeedPlotView::replot() @@ -132,8 +165,8 @@ void SpeedPlotView::replot()
{
if ((m_period == MIN1)
|| (m_period == MIN5)
|| ((m_period == MIN30) && (m_counter30Min == 2))
|| ((m_period == HOUR6) && (m_counter6Hour == 17)))
|| ((m_period == MIN30) && m_averager30Min.isReady())
|| ((m_period == HOUR6) && m_averager6Hour.isReady()) )
viewport()->update();
}
@ -151,11 +184,11 @@ boost::circular_buffer<SpeedPlotView::PointData> &SpeedPlotView::getCurrentData( @@ -151,11 +184,11 @@ boost::circular_buffer<SpeedPlotView::PointData> &SpeedPlotView::getCurrentData(
}
}
int SpeedPlotView::maxYValue()
quint64 SpeedPlotView::maxYValue()
{
boost::circular_buffer<PointData> &queue = getCurrentData();
int maxYValue = 0;
quint64 maxYValue = 0;
for (int id = UP; id < NB_GRAPHS; ++id) {
if (!m_properties[static_cast<GraphID>(id)].enable)
@ -179,7 +212,7 @@ void SpeedPlotView::paintEvent(QPaintEvent *) @@ -179,7 +212,7 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
rect.adjust(4, 4, 0, -4); // Add padding
int maxY = maxYValue();
quint64 maxY = maxYValue();
rect.adjust(0, fontMetrics.height(), 0, 0); // Add top padding for top speed text
@ -263,7 +296,7 @@ void SpeedPlotView::paintEvent(QPaintEvent *) @@ -263,7 +296,7 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
continue;
if (fontMetrics.width(property.name) > legendWidth)
legendWidth = fontMetrics.width(property.name);
legendWidth = fontMetrics.width(property.name);
legendHeight += 1.5 * fontMetrics.height();
}

35
src/gui/properties/speedplotview.h

@ -70,7 +70,7 @@ public: @@ -70,7 +70,7 @@ public:
struct PointData
{
qint64 x;
int y[NB_GRAPHS];
quint64 y[NB_GRAPHS];
};
explicit SpeedPlotView(QWidget *parent = nullptr);
@ -78,7 +78,7 @@ public: @@ -78,7 +78,7 @@ public:
void setGraphEnable(GraphID id, bool enable);
void setViewableLastPoints(TimePeriod period);
void pushPoint(PointData point);
void pushPoint(const PointData &point);
void replot();
@ -86,19 +86,18 @@ protected: @@ -86,19 +86,18 @@ protected:
void paintEvent(QPaintEvent *event) override;
private:
enum PeriodInSeconds
class Averager
{
MIN1_SEC = 60,
MIN5_SEC = 5 * 60,
MIN30_SEC = 30 * 60,
HOUR6_SEC = 6 * 60 * 60
};
enum PointsToSave
{
MIN5_BUF_SIZE = 5 * 60,
MIN30_BUF_SIZE = 10 * 60,
HOUR6_BUF_SIZE = 20 * 60
public:
Averager(int divider, boost::circular_buffer<PointData> &sink);
void push(const PointData &pointData);
bool isReady() const;
private:
const int m_divider;
boost::circular_buffer<PointData> &m_sink;
int m_counter;
PointData m_accumulator;
};
struct GraphProperties
@ -111,19 +110,19 @@ private: @@ -111,19 +110,19 @@ private:
bool enable;
};
int maxYValue();
quint64 maxYValue();
boost::circular_buffer<PointData> &getCurrentData();
boost::circular_buffer<PointData> m_data5Min;
boost::circular_buffer<PointData> m_data30Min;
boost::circular_buffer<PointData> m_data6Hour;
Averager m_averager30Min;
Averager m_averager6Hour;
QMap<GraphID, GraphProperties> m_properties;
TimePeriod m_period;
int m_viewablePointsCount;
int m_counter30Min;
int m_counter6Hour;
};
#endif // SPEEDPLOTVIEW_H

Loading…
Cancel
Save