CryptoByLeo/Src/RSPParser/Iteradores.mqh

402 lines
14 KiB
MQL5
Raw Permalink Normal View History

2026-08-24 21:32:18 -05:00
//+------------------------------------------------------------------+
//| Iteradores.mqh |
//| Copyright 2026, Niquel Mendoza |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Niquel Mendoza"
#property link "https://www.mql5.com"
#property strict
#ifndef CRYPTOBYLEO_RSPPARSER_ITERADORES_MQH
#define CRYPTOBYLEO_RSPPARSER_ITERADORES_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include "Node.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
2026-08-25 08:02:51 -05:00
//+------------------------------------------------------------------+
//| Por defecto |
//+------------------------------------------------------------------+
MQLARTICLES_STRUCTBYTES_CRE(3)
MQLARTICLES_STRUCTBYTES_CRE(4)
MQLARTICLES_STRUCTBYTES_CRE(5)
2026-08-24 21:32:18 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CRSPIteradorBase
{
protected:
CRSPParser* m_ctx; // contrexto
int m_pos; // indice de lectura
int m_cinta_len;
2026-08-25 08:02:51 -05:00
int m_readed_pars;
2026-08-25 08:09:26 -05:00
int m_par_size;
int m_last_pos;
2026-08-24 21:32:18 -05:00
public:
2026-08-25 08:09:26 -05:00
CRSPIteradorBase(CRSPParser* _ctx, const int init_pos, const int psize);
2026-08-24 21:32:18 -05:00
~CRSPIteradorBase(void) {}
//--- Get
2026-08-24 21:32:18 -05:00
virtual __forceinline CRSPNode Get(const string& key) const = 0;
//--- General
// es valido seguir iterando
__forceinline bool IsValid() const { return m_pos < m_cinta_len; }
// avanza un "chunk" entero de lectura
2026-08-24 21:32:18 -05:00
void Next();
// mata el puntero de lecutra..
void Kill() { m_last_pos = m_pos; m_pos = m_cinta_len; }
//--- setters
__forceinline void RecalcLen() { m_cinta_len = m_ctx.m_cinta_pos; }
// setear el puntero de lectura
void operator=(const int p) { m_pos = p; m_readed_pars = 0; }
// lo resetea en la ultima poscion (justo en KEY meta) de la iteracion previa
__forceinline void ResetLast() { m_pos = m_last_pos; m_readed_pars = 0; }
//--- getters
__forceinline int ReadLastPos() const { return m_last_pos; }
__forceinline int ReadPointer() const { return m_pos; }
__forceinline int ReadPars() const { return m_readed_pars; }
//--- at (base indice)
2026-08-24 21:32:18 -05:00
__forceinline CRSPNode At(const int index) const; // obtiene por indice posicion
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-08-25 08:09:26 -05:00
CRSPIteradorBase::CRSPIteradorBase(CRSPParser* _ctx, const int init_pos, const int psize)
: m_ctx(_ctx), m_pos(init_pos), m_cinta_len((_ctx == NULL ? 0 : _ctx.m_cinta_pos)), m_readed_pars(0), m_par_size(psize)
2026-08-24 21:32:18 -05:00
{
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CRSPIteradorBase::Next()
{
if(m_pos >= m_cinta_len)
return;
// avanzamos
2026-08-25 08:09:26 -05:00
m_pos += (RSPDATA_TRIPLET_KEYVALUEMETA * m_par_size);
2026-08-25 08:02:51 -05:00
m_readed_pars++;
2026-08-24 21:32:18 -05:00
// verificamos que en caso qeu el meta sea del tipo metacor entonces paramos ya no hay nada mas que hacer
if(((m_ctx.m_cinta[m_pos + 1] >> TSN_SBL_BIT_START_ENDTYPE)&RSPDATA_MASK_META_IS) != 0) // justo en meta
{
m_last_pos = m_pos;
2026-08-24 21:32:18 -05:00
m_pos = m_cinta_len;
}
2026-08-24 21:32:18 -05:00
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
__forceinline CRSPNode CRSPIteradorBase::At(const int index) const
{
return CRSPNode(m_pos + (index * RSPDATA_TRIPLET_KEYVALUEMETA), m_ctx);
}
//+------------------------------------------------------------------+
//| IOterador por hash perfecto |
//+------------------------------------------------------------------+
2026-08-25 08:02:51 -05:00
#define CRSPIteratorPHashFast TSN::CRSPIteratorPHash<TSN::CGenericHash_string>
#define CRSPIteratorPHashFastP(P) TSN::CRSPIteratorPHash<TSN::CGenericHash_string_##NH>
//---
2026-08-24 21:55:43 -05:00
template <typename TBaseHash>
2026-08-24 21:32:18 -05:00
class CRSPIteratorPHash : public CRSPIteradorBase
{
private:
//--- pfh
int m_offets[]; // offets
ulong m_seeds[]; // seeds
ulong m_key_hash[]; // array de key hashes
ulong m_bucket_l; // Buckets
ulong m_final_table_l; // Tamaño de pos index (tabla final)
2026-08-24 21:55:43 -05:00
bool m_valid_it;
2026-08-24 21:32:18 -05:00
public:
CRSPIteratorPHash(const string& keys[], CRSPParser* _ctx, const int init_pos);
2026-08-25 08:09:26 -05:00
CRSPIteratorPHash() : CRSPIteradorBase(NULL, -1, 0) {}
2026-08-24 21:32:18 -05:00
~CRSPIteratorPHash() {}
//---
using CRSPIteradorBase::operator=;
2026-08-24 21:55:43 -05:00
//----
__forceinline bool IsHashValid() const { return m_valid_it; }
2026-08-24 21:32:18 -05:00
//---
// No se permite modifacion es una tabla de hash perfecta
//--- at por key
CRSPNode operator[](const string& key) const; // obtiene por key
//---
__forceinline CRSPNode Get(const string& key) const override final { return this[key]; }
//---
static const CRSPIteratorPHash EMPTY;
};
//+------------------------------------------------------------------+
2026-08-24 21:55:43 -05:00
template <typename TBaseHash>
2026-08-24 21:32:18 -05:00
const CRSPIteratorPHash CRSPIteratorPHash::EMPTY;
//+------------------------------------------------------------------+
2026-08-24 21:55:43 -05:00
template <typename TBaseHash> CRSPIteratorPHash::CRSPIteratorPHash(const string& keys[], CRSPParser* _ctx, const int init_pos)
2026-08-25 08:09:26 -05:00
: CRSPIteradorBase(_ctx, init_pos, ArraySize(keys))
2026-08-24 21:32:18 -05:00
{
// se asume que keys size = TNumHash (sizeof)
// iteramos por todas las key contruimos hashes
CPerfectHashByLeo<ulong, CSBLHasherGenUl, CSBLHasherGenUl1>* pf = m_ctx.m_pfh;
//---
2026-08-24 21:55:43 -05:00
ulong key_h[];
2026-08-25 08:09:26 -05:00
ArrayResize(key_h, m_par_size);
2026-08-24 21:55:43 -05:00
int off[];
2026-08-25 08:09:26 -05:00
ArrayResize(off, m_par_size);
2026-08-24 21:32:18 -05:00
//---
2026-08-25 08:09:26 -05:00
for(int j = 0; j < m_par_size; j++)
2026-08-24 21:32:18 -05:00
{
key_h[j] = TBaseHash::Hash(keys[j]);
2026-08-25 08:09:26 -05:00
off[j] = (j * RSPDATA_TRIPLET_KEYVALUEMETA) + 1;
2026-08-24 21:32:18 -05:00
}
//---
pf.MaxValSeed(m_ctx.m_max_att++);
2026-08-25 08:09:26 -05:00
pf.InitAlg(m_par_size, 0.70, fmin(m_par_size, 4));
2026-08-24 21:32:18 -05:00
//---
const int fn = pf.m_final_table_size;
m_bucket_l = pf.m_buckets_size_last;
m_final_table_l = pf.m_final_table_size_last;
// Iniciamos..
ArrayResize(m_offets, fn);
ArrayResize(m_key_hash, fn);
ArrayInitialize(m_offets, -1);
ArrayInitialize(m_key_hash, 0ULL);
//---
2026-08-25 10:21:08 -05:00
pf.RunWValue(key_h, off, m_seeds, m_offets, m_key_hash);
2026-08-24 21:32:18 -05:00
}
//+------------------------------------------------------------------+
2026-08-24 21:55:43 -05:00
template <typename TBaseHash>
2026-08-24 21:32:18 -05:00
CRSPNode CRSPIteratorPHash::operator[](const string& key) const
{
//--- calculo del hash
const ulong key_hash = TBaseHash::Hash(key);
//--- alg
const int seed_index = int(key_hash & m_bucket_l);
SBL_HASH_ALG(key_hash, m_seeds[seed_index])
//---
const int fi = int(h & m_final_table_l);
return m_key_hash[fi] == key_hash ? CRSPNode(m_pos + m_offets[fi], m_ctx) : CRSPNode::EMPTY_NODE;
}
//+------------------------------------------------------------------+
//| Iterador por hash custom |
//+------------------------------------------------------------------+
// TNumHashes = cuantos hashes hay
2026-08-25 08:02:51 -05:00
#define CRSPIteratorHashFast(NH ) TSN::CRSPIteratorHash<RSPNODE_NH(NH), TSN::CGenericHash_string>
#define CRSPIteratorHashFastP(NH, P) TSN::CRSPIteratorHash<RSPNODE_NH(NH), TSN::CGenericHash_string_##P>
//---
2026-08-24 21:32:18 -05:00
template <typename TNumHashes, typename TBaseHash>
class CRSPIteratorHash : public CRSPIteradorBase
{
private:
//--- hash
ulong m_hashes[sizeof(TNumHashes)]; // tamaño fijo maxima velocidad
public:
CRSPIteratorHash(const string& keys[], CRSPParser* _ctx, const int init_pos);
2026-08-25 08:09:26 -05:00
CRSPIteratorHash() : CRSPIteradorBase(NULL, -1, 0) {}
2026-08-24 21:32:18 -05:00
~CRSPIteratorHash() {}
//---
using CRSPIteradorBase::operator=;
2026-08-24 21:32:18 -05:00
//---
// modifiacion
2026-08-24 21:55:43 -05:00
void HashPos(const int j, const string& key) { m_hashes[j] = TBaseHash::Hash(key); }
2026-08-24 21:32:18 -05:00
// obtencion de hash
__forceinline ulong HashPos(const int j) { return m_hashes[j]; }
//--- at por key
CRSPNode operator[](const string& key) const; // obtiene por key
//---
__forceinline CRSPNode Get(const string& key) const override final { return this[key]; }
//---
2026-08-24 21:55:43 -05:00
static const CRSPIteratorHash EMPTY;
2026-08-24 21:32:18 -05:00
};
//+------------------------------------------------------------------+
template <typename TNumHashes, typename TBaseHash>
2026-08-24 21:55:43 -05:00
const CRSPIteratorHash CRSPIteratorHash::EMPTY;
2026-08-24 21:32:18 -05:00
//+------------------------------------------------------------------+
template <typename TNumHashes, typename TBaseHash> CRSPIteratorHash::CRSPIteratorHash(const string& keys[], CRSPParser* _ctx, const int init_pos)
2026-08-25 08:09:26 -05:00
: CRSPIteradorBase(_ctx, init_pos, sizeof(TNumHashes))
2026-08-24 21:32:18 -05:00
{
for(int j = 0; j < sizeof(TNumHashes); j++)
m_hashes[j] = TBaseHash::Hash(keys[j]);
2026-08-24 21:55:43 -05:00
}
//+------------------------------------------------------------------+
template <typename TNumHashes, typename TBaseHash>
CRSPNode CRSPIteratorHash::operator[](const string& key) const
{
//--- calculo del hash
const ulong h = TBaseHash::Hash(key);
//--- ahora iteramos
for(int i = 0; i < sizeof(TNumHashes); i++)
{
if(m_hashes[i] == h)
{
// coincide .. aparitr de aqui calculamos..
const int idx = m_pos + (i * RSPDATA_TRIPLET_KEYVALUEMETA);
2026-08-25 08:09:26 -05:00
return CRSPNode(idx + 1, m_ctx);
2026-08-24 21:55:43 -05:00
}
2026-08-24 21:32:18 -05:00
}
2026-08-24 21:55:43 -05:00
//--- No se encontro
return CRSPNode::EMPTY_NODE;
2026-08-24 21:32:18 -05:00
}
//+------------------------------------------------------------------+
2026-08-24 21:55:43 -05:00
//| Iterador por hash custom (dinamico |
2026-08-24 21:32:18 -05:00
//+------------------------------------------------------------------+
2026-08-24 21:55:43 -05:00
// TNumHashes = cuantos hashes hay
2026-08-25 08:02:51 -05:00
#define CRSPIteratorHashDyncFast TSN::CRSPIteratorHashDync<TSN::CGenericHash_string>
#define CRSPIteratorHashDyncFastP(P) TSN::CRSPIteratorHashDync<TSN::CGenericHash_string_##NH>
//---
2026-08-24 21:55:43 -05:00
template <typename TBaseHash>
class CRSPIteratorHashDync : public CRSPIteradorBase
2026-08-24 21:32:18 -05:00
{
2026-08-24 21:55:43 -05:00
private:
//--- hash
ulong m_hashes[]; // tamaño fijo maxima velocidad
public:
CRSPIteratorHashDync(const string& keys[], CRSPParser* _ctx, const int init_pos);
2026-08-25 08:09:26 -05:00
CRSPIteratorHashDync() : CRSPIteradorBase(NULL, -1, 0) {}
2026-08-24 21:55:43 -05:00
~CRSPIteratorHashDync() {}
//---
using CRSPIteradorBase::operator=;
2026-08-24 21:55:43 -05:00
//---
void Size(const int new_s);
2026-08-25 08:09:26 -05:00
__forceinline int Size() const { return m_par_size; }
2026-08-24 21:55:43 -05:00
// modifiacion
void HashPos(const int j, const string& key) { m_hashes[j] = TBaseHash::Hash(key); }
// obtencion de hash
__forceinline ulong HashPos(const int j) { return m_hashes[j]; }
//--- at por key
CRSPNode operator[](const string& key) const; // obtiene por key
//---
__forceinline CRSPNode Get(const string& key) const override final { return this[key]; }
//---
static const CRSPIteratorHashDync EMPTY;
};
2026-08-24 21:32:18 -05:00
//+------------------------------------------------------------------+
2026-08-24 21:55:43 -05:00
template <typename TBaseHash>
const CRSPIteratorHashDync CRSPIteratorHashDync::EMPTY;
//+------------------------------------------------------------------+
template <typename TBaseHash> CRSPIteratorHashDync::CRSPIteratorHashDync(const string& keys[], CRSPParser* _ctx, const int init_pos)
2026-08-25 08:09:26 -05:00
: CRSPIteradorBase(_ctx, init_pos, ArraySize(keys))
2026-08-24 21:55:43 -05:00
{
2026-08-25 08:09:26 -05:00
ArrayResize(m_hashes, m_par_size);
for(int j = 0; j < m_par_size; j++)
2026-08-24 21:55:43 -05:00
m_hashes[j] = TBaseHash::Hash(keys[j]);
}
//+------------------------------------------------------------------+
template <typename TBaseHash>
void CRSPIteratorHashDync::Resize(const int new_s)
{
2026-08-25 10:21:08 -05:00
if(new_s <= m_par_size)
m_par_size = new_s;
2026-08-24 21:55:43 -05:00
else
{
if(new_s > ArraySize(m_hashes))
ArrayResize(m_hashes, new_s, new_s);
2026-08-25 10:21:08 -05:00
m_par_size = new_s;
2026-08-24 21:55:43 -05:00
}
}
//+------------------------------------------------------------------+
template <typename TBaseHash>
CRSPNode CRSPIteratorHashDync::operator[](const string& key) const
2026-08-24 21:32:18 -05:00
{
//--- calculo del hash
const ulong h = TBaseHash::Hash(key);
//--- ahora iteramos
2026-08-25 08:09:26 -05:00
for(int i = 0; i < m_par_size; i++)
2026-08-24 21:32:18 -05:00
{
if(m_hashes[i] == h)
{
// coincide .. aparitr de aqui calculamos..
const int idx = m_pos + (i * RSPDATA_TRIPLET_KEYVALUEMETA);
2026-08-25 08:09:26 -05:00
return CRSPNode(idx + 1, m_ctx);
2026-08-24 21:32:18 -05:00
}
}
//--- No se encontro
return CRSPNode::EMPTY_NODE;
}
2026-08-24 21:55:43 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
template <typename THashBase>
CRSPIteradorBase* CRSPNode::MakeInteligentIterador(const string& keys[]) const
{
if(RSPDATA_IS_NOT_VALID)
return NULL;
//---
const int t = ArraySize(keys);
if(t >= RSPNODE_ITERADOR_MIN_PFH)
{
2026-08-25 10:21:08 -05:00
CRSPIteradorBase* it = new CRSPIteratorPHash<THashBase>(keys, m_ctx, m_idx);
2026-08-24 21:55:43 -05:00
if(!it.IsHashValid())
delete it; // fallo en formarse fallback a normal..
else
return it;
}
//---
return new CRSPIteratorHashDync<THashBase>(keys, m_ctx, m_idx);
}
2026-08-25 08:02:51 -05:00
//---
2026-08-24 21:32:18 -05:00
}
//+------------------------------------------------------------------+
#endif // CRYPTOBYLEO_RSPPARSER_ITERADORES_MQH