mirror of
https://github.com/holub/mame
synced 2025-07-06 02:18:09 +03:00
More phashmap_t usage. Quite some nice effect on larger netlist startup
time. Hash objects can now deal with arbitrary hash width. (nw)
This commit is contained in:
parent
112ad5223f
commit
45e5fab5ff
@ -235,7 +235,7 @@ void setup_t::register_object(device_t &dev, const pstring &name, object_t &obj)
|
||||
else
|
||||
term.init_object(dev, dev.name() + "." + name);
|
||||
|
||||
if (!(m_terminals.add(&term, false)==true))
|
||||
if (!m_terminals.add(term.name(), &term))
|
||||
netlist().error("Error adding %s %s to terminal list\n", objtype_as_astr(term).cstr(), term.name().cstr());
|
||||
NL_VERBOSE_OUT(("%s %s\n", objtype_as_astr(term).cstr(), name.cstr()));
|
||||
}
|
||||
@ -412,48 +412,53 @@ const pstring setup_t::resolve_alias(const pstring &name) const
|
||||
core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool required)
|
||||
{
|
||||
const pstring &tname = resolve_alias(terminal_in);
|
||||
core_terminal_t *ret;
|
||||
int ret;
|
||||
|
||||
ret = m_terminals.find_by_name(tname);
|
||||
ret = m_terminals.index_of(tname);
|
||||
/* look for default */
|
||||
if (ret == NULL)
|
||||
if (ret < 0)
|
||||
{
|
||||
/* look for ".Q" std output */
|
||||
pstring s = tname + ".Q";
|
||||
ret = m_terminals.find_by_name(s);
|
||||
ret = m_terminals.index_of(tname + ".Q");
|
||||
}
|
||||
if (ret == NULL && required)
|
||||
|
||||
core_terminal_t *term = (ret < 0 ? NULL : m_terminals.value_at(ret));
|
||||
|
||||
if (term == NULL && required)
|
||||
netlist().error("terminal %s(%s) not found!\n", terminal_in.cstr(), tname.cstr());
|
||||
if (ret != NULL)
|
||||
if (term != NULL)
|
||||
NL_VERBOSE_OUT(("Found input %s\n", tname.cstr()));
|
||||
return ret;
|
||||
return term;
|
||||
}
|
||||
|
||||
core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, object_t::type_t atype, bool required)
|
||||
{
|
||||
const pstring &tname = resolve_alias(terminal_in);
|
||||
core_terminal_t *ret;
|
||||
int ret;
|
||||
|
||||
ret = m_terminals.find_by_name(tname);
|
||||
ret = m_terminals.index_of(tname);
|
||||
/* look for default */
|
||||
if (ret == NULL && atype == object_t::OUTPUT)
|
||||
if (ret < 0 && atype == object_t::OUTPUT)
|
||||
{
|
||||
/* look for ".Q" std output */
|
||||
pstring s = tname + ".Q";
|
||||
ret = m_terminals.find_by_name(s);
|
||||
ret = m_terminals.index_of(tname + ".Q");
|
||||
}
|
||||
if (ret == NULL && required)
|
||||
if (ret < 0 && required)
|
||||
netlist().error("terminal %s(%s) not found!\n", terminal_in.cstr(), tname.cstr());
|
||||
if (ret != NULL && ret->type() != atype)
|
||||
|
||||
core_terminal_t *term = (ret < 0 ? NULL : m_terminals.value_at(ret));
|
||||
|
||||
if (term != NULL && term->type() != atype)
|
||||
{
|
||||
if (required)
|
||||
netlist().error("object %s(%s) found but wrong type\n", terminal_in.cstr(), tname.cstr());
|
||||
else
|
||||
ret = NULL;
|
||||
term = NULL;
|
||||
}
|
||||
if (ret != NULL)
|
||||
if (term != NULL)
|
||||
NL_VERBOSE_OUT(("Found input %s\n", tname.cstr()));
|
||||
return ret;
|
||||
|
||||
return term;
|
||||
}
|
||||
|
||||
param_t *setup_t::find_param(const pstring ¶m_in, bool required)
|
||||
@ -807,12 +812,13 @@ void setup_t::resolve_inputs()
|
||||
netlist().log("looking for terminals not connected ...");
|
||||
for (std::size_t i = 0; i < m_terminals.size(); i++)
|
||||
{
|
||||
if (!m_terminals[i]->has_net())
|
||||
core_terminal_t *term = m_terminals.value_at(i);
|
||||
if (!term->has_net())
|
||||
errstr += pstring::sprintf("Found terminal %s without a net\n",
|
||||
m_terminals[i]->name().cstr());
|
||||
else if (m_terminals[i]->net().num_cons() == 0)
|
||||
term->name().cstr());
|
||||
else if (term->net().num_cons() == 0)
|
||||
netlist().warning("Found terminal %s without connections",
|
||||
m_terminals[i]->name().cstr());
|
||||
term->name().cstr());
|
||||
}
|
||||
if (errstr != "")
|
||||
netlist().error("%s", errstr.cstr());
|
||||
|
@ -127,9 +127,6 @@ namespace netlist
|
||||
const pstring &name() const { return e1; }
|
||||
};
|
||||
|
||||
//typedef pnamedlist_t<link_t> tagmap_nstring_t;
|
||||
typedef pnamedlist_t<core_terminal_t *> tagmap_terminal_t;
|
||||
|
||||
setup_t(netlist_t *netlist);
|
||||
~setup_t();
|
||||
|
||||
@ -193,9 +190,6 @@ namespace netlist
|
||||
|
||||
bool is_library_item(const pstring &name) const { return m_lib.contains(name); }
|
||||
|
||||
/* not ideal, but needed for save_state */
|
||||
tagmap_terminal_t m_terminals;
|
||||
|
||||
void print_stats() const;
|
||||
|
||||
/* static support functions */
|
||||
@ -207,25 +201,6 @@ namespace netlist
|
||||
|
||||
private:
|
||||
|
||||
netlist_t *m_netlist;
|
||||
|
||||
phashmap_t<pstring, pstring> m_alias;
|
||||
phashmap_t<pstring, param_t *> m_params;
|
||||
phashmap_t<pstring, pstring> m_params_temp;
|
||||
|
||||
plist_t<link_t> m_links;
|
||||
|
||||
factory_list_t *m_factory;
|
||||
|
||||
plist_t<pstring> m_models;
|
||||
|
||||
int m_proxy_cnt;
|
||||
|
||||
pstack_t<pstring> m_stack;
|
||||
source_t::list_t m_sources;
|
||||
plist_t<pstring> m_lib;
|
||||
|
||||
|
||||
void connect_terminals(core_terminal_t &in, core_terminal_t &out);
|
||||
void connect_input_output(core_terminal_t &in, core_terminal_t &out);
|
||||
void connect_terminal_output(terminal_t &in, core_terminal_t &out);
|
||||
@ -238,6 +213,25 @@ namespace netlist
|
||||
const pstring resolve_alias(const pstring &name) const;
|
||||
devices::nld_base_proxy *get_d_a_proxy(core_terminal_t &out);
|
||||
|
||||
netlist_t *m_netlist;
|
||||
|
||||
phashmap_t<pstring, pstring> m_alias;
|
||||
phashmap_t<pstring, param_t *> m_params;
|
||||
phashmap_t<pstring, pstring> m_params_temp;
|
||||
phashmap_t<pstring, core_terminal_t *> m_terminals;
|
||||
|
||||
plist_t<link_t> m_links;
|
||||
|
||||
factory_list_t *m_factory;
|
||||
|
||||
plist_t<pstring> m_models;
|
||||
|
||||
int m_proxy_cnt;
|
||||
|
||||
pstack_t<pstring> m_stack;
|
||||
source_t::list_t m_sources;
|
||||
plist_t<pstring> m_lib;
|
||||
|
||||
#if 0
|
||||
template <class T>
|
||||
void remove_start_with(T &hm, pstring &sw)
|
||||
|
@ -620,23 +620,41 @@ public:
|
||||
template <class C>
|
||||
struct phash_functor
|
||||
{
|
||||
unsigned hash(const C &v) const { return (unsigned) v; }
|
||||
phash_functor()
|
||||
{}
|
||||
phash_functor(const C &v)
|
||||
{
|
||||
m_hash = v;
|
||||
}
|
||||
friend unsigned operator%(const phash_functor &lhs, const unsigned &rhs) { return lhs.m_hash % rhs; }
|
||||
bool operator==(const phash_functor &lhs) const { return (m_hash == lhs.m_hash); }
|
||||
private:
|
||||
unsigned m_hash;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct phash_functor<pstring>
|
||||
{
|
||||
#if 1
|
||||
#if 1
|
||||
unsigned hash(const pstring &v) const
|
||||
phash_functor()
|
||||
{}
|
||||
phash_functor(const pstring &v)
|
||||
{
|
||||
/* modified djb2 */
|
||||
const char *string = v.cstr();
|
||||
unsigned result = *string++;
|
||||
for (UINT8 c = *string++; c != 0; c = *string++)
|
||||
result = (result*33) ^ c;
|
||||
return result;
|
||||
unsigned result = 5381;
|
||||
for (UINT8 c = *string; c != 0; c = *string++)
|
||||
result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ c;
|
||||
//result = (result*33) ^ c;
|
||||
m_hash = result;
|
||||
}
|
||||
#else
|
||||
friend unsigned operator%(const phash_functor<pstring> &lhs, const unsigned &rhs) { return lhs.m_hash % rhs; }
|
||||
bool operator==(const phash_functor<pstring> &lhs) const { return (m_hash == lhs.m_hash); }
|
||||
private:
|
||||
unsigned m_hash;
|
||||
};
|
||||
|
||||
#if 0
|
||||
#if 0
|
||||
unsigned hash(const pstring &v) const
|
||||
{
|
||||
/* Fowler–Noll–Vo hash - FNV-1 */
|
||||
@ -647,7 +665,6 @@ struct phash_functor<pstring>
|
||||
// result = (result ^ c) * 16777619; FNV 1a
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
unsigned hash(const pstring &v) const
|
||||
{
|
||||
@ -667,13 +684,13 @@ struct phash_functor<pstring>
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
template <class K, class V, class H = phash_functor<K> >
|
||||
class phashmap_t
|
||||
{
|
||||
public:
|
||||
phashmap_t() : m_hash(17)
|
||||
phashmap_t() : m_hash(37)
|
||||
{
|
||||
for (unsigned i=0; i<m_hash.size(); i++)
|
||||
m_hash[i] = -1;
|
||||
@ -686,11 +703,11 @@ public:
|
||||
struct element_t
|
||||
{
|
||||
element_t() { }
|
||||
element_t(K key, unsigned hash, V value)
|
||||
element_t(const K &key, const H &hash, const V &value)
|
||||
: m_key(key), m_hash(hash), m_value(value), m_next(-1)
|
||||
{}
|
||||
K m_key;
|
||||
unsigned m_hash;
|
||||
H m_hash;
|
||||
V m_value;
|
||||
int m_next;
|
||||
};
|
||||
@ -736,15 +753,14 @@ public:
|
||||
* and accept that outside we will not have a prime
|
||||
*
|
||||
*/
|
||||
if (m_values.size() > m_hash.size())
|
||||
if (m_values.size() * 3 / 2 > 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 H hash(key);
|
||||
const unsigned pos = hash % m_hash.size();
|
||||
if (m_hash[pos] == -1)
|
||||
{
|
||||
@ -788,8 +804,7 @@ private:
|
||||
|
||||
int get_idx(const K &key) const
|
||||
{
|
||||
H h;
|
||||
const unsigned hash=h.hash(key);
|
||||
H hash(key);
|
||||
const unsigned pos = hash % m_hash.size();
|
||||
|
||||
for (int ep = m_hash[pos]; ep != -1; ep = m_values[ep].m_next)
|
||||
|
Loading…
Reference in New Issue
Block a user