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 | | |
|
2026-08-24 21:32:18 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | class CRSPIteradorBase
|
| | | {
|
| | | protected:
|
| | | CRSPParser* m_ctx; // contrexto
|
| | | int m_pos; // indice de lectura
|
2026-09-02 07:22:44 -05:00 | | | int m_cinta_pos;
|
2026-08-25 08:02:51 -05:00 | | | int m_readed_pars;
|
2026-08-25 08:09:26 -05:00 | | | int m_par_size;
|
2026-08-26 08:21:19 -05:00 | | | 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) {}
|
| | |
|
2026-08-26 08:21:19 -05:00 | | | //--- Get
|
2026-08-24 21:32:18 -05:00 | | | virtual __forceinline CRSPNode Get(const string& key) const = 0;
|
| | |
|
2026-08-26 08:21:19 -05:00 | | | //--- General
|
| | | // es valido seguir iterando
|
2026-09-02 07:22:44 -05:00 | | | __forceinline bool IsValid() const { return m_pos < m_cinta_pos; }
|
2026-08-26 08:21:19 -05:00 | | | // avanza un "chunk" entero de lectura
|
2026-08-24 21:32:18 -05:00 | | | void Next();
|
2026-08-26 08:21:19 -05:00 | | | // mata el puntero de lecutra..
|
2026-09-02 07:22:44 -05:00 | | | void Kill() { m_last_pos = m_pos; m_pos = m_cinta_pos; }
|
2026-08-26 08:21:19 -05:00 | | |
|
| | | //--- setters
|
2026-09-02 07:22:44 -05:00 | | | __forceinline void RecalcLen() { m_cinta_pos = m_ctx.m_cinta_pos; }
|
2026-09-02 08:18:46 -05:00 | | | // setear el puntero de lectura
|
| | | // indica p que es el indice del grupo donde uqieres emepzar la iteracion
|
| | | void operator=(const int p) { m_pos = p * RSPDATA_TRIPLET_KEYVALUEMETA; m_readed_pars = 0; }
|
| | |
|
| | | // nota uqe los += y -= avanzas de a grupos de 3.. NO UN "m_par_size"
|
| | | // Eso solo lo hace el next
|
| | | // avanzamos de agrupos
|
| | | void operator+=(const int p) { m_pos += p * RSPDATA_TRIPLET_KEYVALUEMETA; }
|
| | | void operator-=(const int p) { m_pos -= p * RSPDATA_TRIPLET_KEYVALUEMETA; }
|
| | |
|
| | |
|
2026-08-26 08:21:19 -05:00 | | | // 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)
|
2026-09-02 07:22:44 -05:00 | | | : m_ctx(_ctx), m_pos(init_pos), m_cinta_pos((_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()
|
| | | {
|
2026-09-02 07:22:44 -05:00 | | | if(m_pos >= m_cinta_pos)
|
2026-08-24 21:32:18 -05:00 | | | 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
|
2026-08-26 08:21:19 -05:00 | | | {
|
| | | m_last_pos = m_pos;
|
2026-09-02 07:22:44 -05:00 | | | m_pos = m_cinta_pos;
|
2026-08-26 08:21:19 -05:00 | | | }
|
2026-08-24 21:32:18 -05:00 | | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | __forceinline CRSPNode CRSPIteradorBase::At(const int index) const
|
| | | {
|
2026-09-02 07:22:44 -05:00 | | | return CRSPNode(m_pos + (index * (RSPDATA_TRIPLET_KEYVALUEMETA * m_par_size)), m_ctx);
|
2026-08-24 21:32:18 -05:00 | | | }
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| 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() {}
|
| | |
|
2026-08-26 08:21:19 -05:00 | | | //---
|
| | | 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-31 20:37:20 -05:00 | | | #define CRSPIteratorHashFast(NH ) TSN::CRSPIteratorHash<MQLA_B(NH), TSN::CGenericHash_string>
|
| | | #define CRSPIteratorHashFastP(NH, P) TSN::CRSPIteratorHash<MQLA_B(NH), TSN::CGenericHash_string_##P>
|
2026-08-25 08:02:51 -05:00 | | |
|
| | | //---
|
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() {}
|
| | |
|
2026-08-26 08:21:19 -05:00 | | | //---
|
| | | 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() {}
|
| | |
|
2026-08-26 08:21:19 -05:00 | | | //---
|
| | | 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
|