137 lines
No EOL
5.1 KiB
MQL5
137 lines
No EOL
5.1 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| EventJournal.mqh |
|
|
//| Copyright 2026, MetaQuotes Ltd. |
|
|
//| www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#ifndef REQUEST_LATENCY_LAB_EVENT_JOURNAL_MQH
|
|
#define REQUEST_LATENCY_LAB_EVENT_JOURNAL_MQH
|
|
|
|
#include "..\..\Include\RequestLatencyLab\Models.mqh"
|
|
|
|
class CEventJournal
|
|
{
|
|
private:
|
|
LabEvent m_events[];
|
|
int m_capacity;
|
|
int m_count;
|
|
ulong m_next_sequence; // event_sequence - порядок регистрации
|
|
ulong m_records_lost; // записи, не поместившиеся в буфер
|
|
ulong m_high_watermark; // максимум занятости буфера
|
|
string m_session_id;
|
|
|
|
public:
|
|
CEventJournal(void);
|
|
bool Init(const int capacity, const string session_id);
|
|
void Clear(void)
|
|
{
|
|
m_count = 0;
|
|
}
|
|
int Count() const { return(m_count); }
|
|
int Capacity() const { return(m_capacity); }
|
|
ulong NextSequence() const { return(m_next_sequence); }
|
|
ulong LostCount() const { return(m_records_lost); }
|
|
ulong HighWatermark() const { return(m_high_watermark); }
|
|
//--- регистрация события; возвращает event_sequence
|
|
bool Add(const LabEvent &event, ulong &event_sequence);
|
|
//--- удобная регистрация типизированной записи
|
|
bool AddTyped(const ENUM_LAB_RECORD_KIND kind, const ulong local_time_us,
|
|
const ulong origin_sequence, const string payload_json,
|
|
const string quality_code);
|
|
//--- фиксация времени выхода обработчика по event_sequence (п.11 аудита)
|
|
bool SetExitTime(const ulong event_sequence, const ulong exit_us);
|
|
bool GetByIndex(const int i, LabEvent &out) const;
|
|
//--- освобождение места для последующих событий после контрольного
|
|
//--- сохранения (без молчаливой потери: потерянные уже учтены)
|
|
void DropPersisted(const int persisted_count, ulong &dropped);
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Внешние определения методов. |
|
|
//+------------------------------------------------------------------+
|
|
CEventJournal::CEventJournal(void)
|
|
{
|
|
m_capacity = 0;
|
|
m_count = 0;
|
|
m_next_sequence = 1;
|
|
m_records_lost = 0;
|
|
m_high_watermark = 0;
|
|
m_session_id = "";
|
|
}
|
|
bool CEventJournal::Init(const int capacity, const string session_id)
|
|
{
|
|
m_capacity = capacity;
|
|
m_session_id = session_id;
|
|
m_count = 0;
|
|
m_next_sequence = 1;
|
|
m_records_lost = 0;
|
|
m_high_watermark = 0;
|
|
if(ArrayResize(m_events, m_capacity) != m_capacity)
|
|
return(false);
|
|
return(true);
|
|
}
|
|
bool CEventJournal::Add(const LabEvent &event, ulong &event_sequence)
|
|
{
|
|
if(m_capacity <= 0 || m_count >= m_capacity)
|
|
{
|
|
m_records_lost++;
|
|
return(false);
|
|
}
|
|
m_count++;
|
|
m_events[m_count - 1] = event;
|
|
m_events[m_count - 1].session_id = m_session_id;
|
|
m_events[m_count - 1].event_sequence = m_next_sequence;
|
|
event_sequence = m_next_sequence;
|
|
m_next_sequence++;
|
|
if((ulong)m_count > m_high_watermark)
|
|
m_high_watermark = (ulong)m_count;
|
|
return(true);
|
|
}
|
|
bool CEventJournal::AddTyped(const ENUM_LAB_RECORD_KIND kind, const ulong local_time_us,
|
|
const ulong origin_sequence, const string payload_json,
|
|
const string quality_code)
|
|
{
|
|
LabEvent e;
|
|
e.Zero();
|
|
e.kind = kind;
|
|
e.local_time_us = local_time_us;
|
|
e.origin_sequence = origin_sequence;
|
|
e.payload_json = payload_json;
|
|
e.quality_code = quality_code;
|
|
ulong seq = 0;
|
|
return(Add(e, seq));
|
|
}
|
|
bool CEventJournal::SetExitTime(const ulong event_sequence, const ulong exit_us)
|
|
{
|
|
for(int i = 0; i < m_count; i++)
|
|
if(m_events[i].event_sequence == event_sequence)
|
|
{
|
|
m_events[i].handler_exit_us = exit_us;
|
|
return(true);
|
|
}
|
|
return(false);
|
|
}
|
|
bool CEventJournal::GetByIndex(const int i, LabEvent &out) const
|
|
{
|
|
if(i < 0 || i >= m_count)
|
|
return(false);
|
|
out = m_events[i];
|
|
return(true);
|
|
}
|
|
void CEventJournal::DropPersisted(const int persisted_count, ulong &dropped)
|
|
{
|
|
dropped = 0;
|
|
if(persisted_count <= 0)
|
|
return;
|
|
if(persisted_count >= m_count)
|
|
{
|
|
dropped = m_count;
|
|
m_count = 0;
|
|
return;
|
|
}
|
|
dropped = persisted_count;
|
|
for(int i = persisted_count; i < m_count; i++)
|
|
m_events[i - persisted_count] = m_events[i];
|
|
m_count -= persisted_count;
|
|
}
|
|
|
|
#endif // REQUEST_LATENCY_LAB_EVENT_JOURNAL_MQH
|
|
//+------------------------------------------------------------------+ |