Init Commit

This commit is contained in:
2021-12-27 23:16:23 +08:00
commit 94bddf23c9
5 changed files with 187 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.idea/
cmake-build-*/

25
CMakeLists.txt Normal file
View File

@@ -0,0 +1,25 @@
cmake_minimum_required(VERSION 3.21)
project(RateSeveral)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt5 COMPONENTS
Core
REQUIRED)
add_executable(RateSeveral main.cpp RateSeveral.cpp RateSeveral.h)
target_link_libraries(RateSeveral
Qt5::Core
)
if (WIN32 AND MSVC)
set(QT_INSTALL_PATH "${CMAKE_PREFIX_PATH}")
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND
"${QT_INSTALL_PATH}/bin/windeployqt.exe"
"$<TARGET_FILE_NAME:${PROJECT_NAME}>")
endif ()

87
RateSeveral.cpp Normal file
View File

@@ -0,0 +1,87 @@
//
// Created by fly on 2021/12/27.
//
#include "RateSeveral.h"
#include <QDateTime>
#include <QDebug>
RateSeveral::RateSeveral(QObject *parent) :
QObject(parent),
timer(this) {
connect(&timer, SIGNAL(timeout()), this, SLOT(onTimerTimeout()));
}
void RateSeveral::setTimerInterval(qint32 second) {
timer.start(second * 1000);
auto a = timer.isActive();
}
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;
}

52
RateSeveral.h Normal file
View File

@@ -0,0 +1,52 @@
//
// Created by fly on 2021/12/27.
//
#ifndef RATESEVERAL_RATESEVERAL_H
#define RATESEVERAL_RATESEVERAL_H
#include <QObject>
#include <QPair>
#include <QList>
#include <QAtomicInt>
#include <QVector>
#include <QTimer>
#include <QReadWriteLock>
class RateSeveral : public QObject {
Q_OBJECT
public:
explicit RateSeveral(QObject *parent = nullptr);
void setTimerInterval(qint32 second);
void addRateInterval(quint32 second);
void removeRateInterval(quint32 second);
void record(quint32 val = 1);
quint32 getMaxListSize() const;
void setMaxListSize(quint32 maxSize);
signals:
void RateSignals(quint32 interval, quint32 rate);
protected slots:
void onTimerTimeout();
protected:
QReadWriteLock intervalLock;
QReadWriteLock listLock;
quint32 maxListSize{1000};
QTimer timer;
QVector<quint32> vInterval;
QList<QPair<qint64, QAtomicInteger<quint32>>> recordList;
QAtomicInteger<qint64> recordTimestamp;
};
#endif //RATESEVERAL_RATESEVERAL_H

21
main.cpp Normal file
View File

@@ -0,0 +1,21 @@
#include <QCoreApplication>
#include <QDebug>
#include <QDebug>
#include "RateSeveral.h"
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
RateSeveral rateSeveral;
rateSeveral.addRateInterval(1);
rateSeveral.addRateInterval(10);
rateSeveral.addRateInterval(60);
rateSeveral.addRateInterval(3600);
rateSeveral.setTimerInterval(1);
QObject::connect(&rateSeveral, &RateSeveral::RateSignals, [](quint32 interval, quint32 rate) {
qInfo() << interval << "\t" << rate;
});
rateSeveral.record(100);
return QCoreApplication::exec();
}