Update 更新文档
This commit is contained in:
256
cleaned_source_code/Sqbase/qdatabuffer.cpp
Normal file
256
cleaned_source_code/Sqbase/qdatabuffer.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
#include "qdatabuffer.h"
|
||||
#include <QDebug>
|
||||
#include <QThread>
|
||||
#include <QDateTime>
|
||||
QDataBuffer* QDataBuffer::instance()
|
||||
{
|
||||
static QDataBuffer instance;
|
||||
return &instance;
|
||||
}
|
||||
QDataBuffer::QDataBuffer(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_cleanupTimer(new QTimer(this))
|
||||
, m_statsUpdateTimer(new QTimer(this))
|
||||
{
|
||||
m_cleanupTimer->setInterval(30000);
|
||||
connect(m_cleanupTimer, &QTimer::timeout, this, &QDataBuffer::cleanupExpiredPackets);
|
||||
m_cleanupTimer->start();
|
||||
m_statsUpdateTimer->setInterval(1000);
|
||||
connect(m_statsUpdateTimer, &QTimer::timeout, this, &QDataBuffer::updateStatistics);
|
||||
m_statsUpdateTimer->start();
|
||||
m_rateTimer.start();
|
||||
}
|
||||
QDataBuffer::~QDataBuffer()
|
||||
{
|
||||
m_cleanupTimer->stop();
|
||||
m_statsUpdateTimer->stop();
|
||||
}
|
||||
void QDataBuffer::setBufferSize(int maxSize)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_maxBufferSize = maxSize;
|
||||
}
|
||||
void QDataBuffer::setFlowControlEnabled(bool enabled)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_flowControlEnabled = enabled;
|
||||
}
|
||||
void QDataBuffer::setMaxPacketsPerSecond(int maxRate)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_maxPacketsPerSecond = maxRate;
|
||||
}
|
||||
bool QDataBuffer::enqueue(const DataPacket& packet)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (m_paused) {
|
||||
emit packetDropped(packet, "Buffer paused");
|
||||
return false;
|
||||
}
|
||||
if (shouldDropPacket(packet)) {
|
||||
m_stats.droppedPackets++;
|
||||
emit packetDropped(packet, "Flow control");
|
||||
return false;
|
||||
}
|
||||
if (m_buffer.size() + m_highPriorityBuffer.size() >= m_maxBufferSize) {
|
||||
m_stats.droppedPackets++;
|
||||
emit bufferOverflow(packet.stockCode, packet.type);
|
||||
emit packetDropped(packet, "Buffer overflow");
|
||||
return false;
|
||||
}
|
||||
m_buffer.enqueue(packet);
|
||||
m_stats.totalPackets++;
|
||||
m_currentSecondPackets++;
|
||||
m_notEmpty.wakeOne();
|
||||
return true;
|
||||
}
|
||||
bool QDataBuffer::enqueueHighPriority(const DataPacket& packet)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (m_paused) {
|
||||
emit packetDropped(packet, "Buffer paused");
|
||||
return false;
|
||||
}
|
||||
if (m_highPriorityBuffer.size() + m_buffer.size() >= m_maxBufferSize) {
|
||||
m_stats.droppedPackets++;
|
||||
emit bufferOverflow(packet.stockCode, packet.type);
|
||||
emit packetDropped(packet, "Buffer overflow");
|
||||
return false;
|
||||
}
|
||||
m_highPriorityBuffer.enqueue(packet);
|
||||
m_stats.totalPackets++;
|
||||
m_currentSecondPackets++;
|
||||
m_notEmpty.wakeOne();
|
||||
return true;
|
||||
}
|
||||
DataPacket QDataBuffer::dequeue(int timeoutMs)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
while (m_highPriorityBuffer.isEmpty() && m_buffer.isEmpty() && !m_paused) {
|
||||
if (!m_notEmpty.wait(&m_mutex, timeoutMs)) {
|
||||
return DataPacket(DataPacketType::Unknown, "", QVariant());
|
||||
}
|
||||
}
|
||||
if (!m_highPriorityBuffer.isEmpty()) {
|
||||
DataPacket packet = m_highPriorityBuffer.dequeue();
|
||||
m_stats.processedPackets++;
|
||||
return packet;
|
||||
}
|
||||
if (!m_buffer.isEmpty()) {
|
||||
DataPacket packet = m_buffer.dequeue();
|
||||
m_stats.processedPackets++;
|
||||
return packet;
|
||||
}
|
||||
return DataPacket(DataPacketType::Unknown, "", QVariant());
|
||||
}
|
||||
QList<DataPacket> QDataBuffer::dequeueBatch(int maxCount, int timeoutMs)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
QList<DataPacket> result;
|
||||
while (m_highPriorityBuffer.isEmpty() && m_buffer.isEmpty() && !m_paused) {
|
||||
if (!m_notEmpty.wait(&m_mutex, timeoutMs)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
while (!m_highPriorityBuffer.isEmpty() && result.size() < maxCount) {
|
||||
result.append(m_highPriorityBuffer.dequeue());
|
||||
m_stats.processedPackets++;
|
||||
}
|
||||
while (!m_buffer.isEmpty() && result.size() < maxCount) {
|
||||
result.append(m_buffer.dequeue());
|
||||
m_stats.processedPackets++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
bool QDataBuffer::isEmpty() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_highPriorityBuffer.isEmpty() && m_buffer.isEmpty();
|
||||
}
|
||||
int QDataBuffer::size() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_highPriorityBuffer.size() + m_buffer.size();
|
||||
}
|
||||
int QDataBuffer::getQueueSize(DataPacketType type) const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
int count = 0;
|
||||
for (const DataPacket& packet : m_highPriorityBuffer) {
|
||||
if (packet.type == type) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
for (const DataPacket& packet : m_buffer) {
|
||||
if (packet.type == type) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
FlowStatistics QDataBuffer::getStatistics() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_stats;
|
||||
}
|
||||
void QDataBuffer::pause()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_paused = true;
|
||||
emit flowControlActivated(true);
|
||||
}
|
||||
void QDataBuffer::resume()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_paused = false;
|
||||
m_notEmpty.wakeAll();
|
||||
emit flowControlActivated(false);
|
||||
}
|
||||
bool QDataBuffer::isPaused() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_paused;
|
||||
}
|
||||
void QDataBuffer::clear()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_highPriorityBuffer.clear();
|
||||
m_buffer.clear();
|
||||
}
|
||||
void QDataBuffer::clearByType(DataPacketType type)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
QQueue<DataPacket> newHighPriority;
|
||||
for (const DataPacket& packet : m_highPriorityBuffer) {
|
||||
if (packet.type != type) {
|
||||
newHighPriority.enqueue(packet);
|
||||
}
|
||||
}
|
||||
m_highPriorityBuffer = newHighPriority;
|
||||
QQueue<DataPacket> newBuffer;
|
||||
for (const DataPacket& packet : m_buffer) {
|
||||
if (packet.type != type) {
|
||||
newBuffer.enqueue(packet);
|
||||
}
|
||||
}
|
||||
m_buffer = newBuffer;
|
||||
}
|
||||
void QDataBuffer::clearByStock(const QString& stockCode)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
QQueue<DataPacket> newHighPriority;
|
||||
for (const DataPacket& packet : m_highPriorityBuffer) {
|
||||
if (packet.stockCode != stockCode) {
|
||||
newHighPriority.enqueue(packet);
|
||||
}
|
||||
}
|
||||
m_highPriorityBuffer = newHighPriority;
|
||||
QQueue<DataPacket> newBuffer;
|
||||
for (const DataPacket& packet : m_buffer) {
|
||||
if (packet.stockCode != stockCode) {
|
||||
newBuffer.enqueue(packet);
|
||||
}
|
||||
}
|
||||
m_buffer = newBuffer;
|
||||
}
|
||||
void QDataBuffer::updateStatistics()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (m_rateTimer.elapsed() >= 1000) {
|
||||
m_stats.packetsPerSecond = static_cast<double>(m_currentSecondPackets) * 1000 / m_rateTimer.elapsed();
|
||||
m_currentSecondPackets = 0;
|
||||
m_rateTimer.restart();
|
||||
}
|
||||
m_stats.updateStats(m_stats.totalPackets, m_stats.droppedPackets, m_stats.processedPackets);
|
||||
locker.unlock();
|
||||
emit statisticsUpdated(m_stats);
|
||||
}
|
||||
bool QDataBuffer::shouldDropPacket(const DataPacket& packet) const
|
||||
{
|
||||
if (!m_flowControlEnabled) {
|
||||
return false;
|
||||
}
|
||||
if (m_currentSecondPackets >= m_maxPacketsPerSecond) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void QDataBuffer::cleanupExpiredPackets()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
QQueue<DataPacket> newHighPriority;
|
||||
for (const DataPacket& packet : m_highPriorityBuffer) {
|
||||
if (packet.timestamp.secsTo(now) < 300) {
|
||||
newHighPriority.enqueue(packet);
|
||||
}
|
||||
}
|
||||
m_highPriorityBuffer = newHighPriority;
|
||||
QQueue<DataPacket> newBuffer;
|
||||
for (const DataPacket& packet : m_buffer) {
|
||||
if (packet.timestamp.secsTo(now) < 120) {
|
||||
newBuffer.enqueue(packet);
|
||||
}
|
||||
}
|
||||
m_buffer = newBuffer;
|
||||
}
|
||||
Reference in New Issue
Block a user