89 lines
2.4 KiB
C++
89 lines
2.4 KiB
C++
//
|
|
// Created by fly on 2021/12/27.
|
|
//
|
|
|
|
#include "RateSeveral.h"
|
|
#include <QDateTime>
|
|
|
|
|
|
RateSeveral::RateSeveral(QObject *parent) :
|
|
QObject(parent),
|
|
timer(this) {
|
|
connect(&timer, SIGNAL(timeout()), this, SLOT(onTimerTimeout()));
|
|
}
|
|
|
|
RateSeveral::~RateSeveral() {
|
|
timer.stop();
|
|
}
|
|
|
|
void RateSeveral::setTimerInterval(qint32 second) {
|
|
timer.start(second * 1000);
|
|
}
|
|
|
|
void RateSeveral::addRateInterval(quint32 second) {
|
|
if (vInterval.end() == std::find(vInterval.begin(), vInterval.end(), second)) {
|
|
intervalLock.lockForWrite();
|
|
vInterval.push_back(second);
|
|
intervalLock.unlock();
|
|
}
|
|
}
|
|
|
|
void RateSeveral::removeRateInterval(quint32 second) {
|
|
auto iter = std::find(vInterval.begin(), vInterval.end(), second);
|
|
if (vInterval.end() != iter) {
|
|
intervalLock.lockForWrite();
|
|
vInterval.erase(iter);
|
|
intervalLock.unlock();
|
|
}
|
|
}
|
|
|
|
void RateSeveral::record(quint32 val) {
|
|
auto timestamp = QDateTime::currentSecsSinceEpoch();
|
|
auto expected = recordTimestamp.loadAcquire();
|
|
if (timestamp != expected && recordTimestamp.testAndSetAcquire(expected, timestamp)) {
|
|
listLock.lockForWrite();
|
|
recordList.push_back({timestamp, 0});
|
|
listLock.unlock();
|
|
}
|
|
recordList.last().second.fetchAndAddAcquire(val);
|
|
}
|
|
|
|
void RateSeveral::onTimerTimeout() {
|
|
intervalLock.lockForRead();
|
|
auto interval = vInterval;
|
|
intervalLock.unlock();
|
|
auto timestamp = QDateTime::currentSecsSinceEpoch();
|
|
quint32 maxInterval = 0;
|
|
auto eraseIter = recordList.end();
|
|
for (auto val: interval) {
|
|
auto lastTimestamp = timestamp - val - 1;
|
|
quint32 sum = 0;
|
|
listLock.lockForRead();
|
|
auto iter = recordList.begin();
|
|
for (; iter != recordList.end() && iter->first > lastTimestamp; ++iter) {
|
|
sum += iter->second;
|
|
}
|
|
listLock.unlock();
|
|
|
|
if (val > maxInterval) {
|
|
maxInterval = val;
|
|
eraseIter = iter;
|
|
}
|
|
emit RateSignals(val, sum);
|
|
}
|
|
if (eraseIter != recordList.end() &&
|
|
(maxListSize ? maxListSize > recordList.size() : maxInterval * 2 > recordList.size())) {
|
|
listLock.lockForWrite();
|
|
recordList.erase(eraseIter, recordList.end());
|
|
listLock.unlock();
|
|
}
|
|
}
|
|
|
|
quint32 RateSeveral::getMaxListSize() const {
|
|
return maxListSize;
|
|
}
|
|
|
|
void RateSeveral::setMaxListSize(quint32 maxSize) {
|
|
RateSeveral::maxListSize = maxSize;
|
|
}
|