diff --git a/src/emu/netlist/plib/plists.h b/src/emu/netlist/plib/plists.h index a470d4eee7c..ab8ebf414c7 100644 --- a/src/emu/netlist/plib/plists.h +++ b/src/emu/netlist/plib/plists.h @@ -12,6 +12,7 @@ #include #include +#include #include "palloc.h" #include "pstring.h" @@ -66,6 +67,11 @@ public: ATTR_HOT std::size_t size() const { return m_capacity; } + void resize(const std::size_t new_size) + { + set_capacity(new_size); + } + protected: ATTR_COLD void set_capacity(const std::size_t new_capacity) { @@ -614,13 +620,15 @@ public: template struct phash_functor { - unsigned hash(const C &v) { return (unsigned) v; } + unsigned hash(const C &v) const { return (unsigned) v; } }; template <> struct phash_functor { - unsigned hash(const pstring &v) +#if 1 +#if 1 + unsigned hash(const pstring &v) const { const char *string = v.cstr(); unsigned result = *string++; @@ -628,19 +636,53 @@ struct phash_functor result = (result*33) ^ c; return result; } +#else + unsigned hash(const pstring &v) const + { + /* Fowler–Noll–Vo hash - FNV-1 */ + const char *string = v.cstr(); + unsigned result = 2166136261; + for (UINT8 c = *string++; c != 0; c = *string++) + result = (result * 16777619) ^ c; + // result = (result ^ c) * 16777619; FNV 1a + return result; + } +#endif +#else + unsigned hash(const pstring &v) const + { + /* jenkins one at a time algo */ + unsigned result = 0; + const char *string = v.cstr(); + while (*string) + { + result += *string; + string++; + result += (result << 10); + result ^= (result >> 6); + } + result += (result << 3); + result ^= (result >> 11); + result += (result << 15); + return result; + } +#endif }; -/* some primes 53, 97, 193, 389, 769, 1543, 3079, 6151 */ template > class phashmap_t { public: - phashmap_t() : m_hash(389) + phashmap_t() : m_hash(17) { for (unsigned i=0; i= 0) + cnt++; + const unsigned s = m_values.size(); + if (s>0) + printf("phashmap: %d elements %d hashsize, percent in overflow: %d\n", s, (unsigned) m_hash.size(), (s - cnt) * 100 / s); + else + printf("phashmap: No elements .. \n"); + } m_values.clear(); for (unsigned i=0; i= n >=0 + * + * and accept that outside we will not have a prime + * + */ + if (m_values.size() > m_hash.size()) + { + unsigned n = std::sqrt( 2 * m_hash.size()); + n = n * n + n + 41; + m_hash.resize(n); + rebuild(); + } + const H h; const unsigned hash=h.hash(key); const unsigned pos = hash % m_hash.size(); if (m_hash[pos] == -1) @@ -740,6 +809,18 @@ private: return -1; } + void rebuild() + { + for (unsigned i=0; i m_values; parray_t m_hash; };