mql5-execution-microstructu.../Include/RequestLatencyLab/EventJournal.mqh

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
//+------------------------------------------------------------------+