// // Created by fly on 2021/12/27. // #include "RateSeveral.h" #include RateSeveral::RateSeveral(QObject *parent) : QObject(parent), timer(this) { connect(&timer, SIGNAL(timeout()), this, SLOT(onTimerTimeout())); } 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; }