summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@arcor.de>2015-07-20 00:07:37 +0200
committer couriersud <couriersud@arcor.de>2015-07-20 22:35:25 +0200
commit45e5fab5ff31f96e95f6eabf793b54328181b483 (patch)
treed72db295b7f003bfa75e4eb49773a593a275116a
parent112ad5223f6dcab2f29997606674222b4458ddc7 (diff)
More phashmap_t usage. Quite some nice effect on larger netlist startup
time. Hash objects can now deal with arbitrary hash width. (nw)
-rw-r--r--src/emu/netlist/nl_setup.c52
-rw-r--r--src/emu/netlist/nl_setup.h32
-rw-r--r--src/emu/netlist/plib/plists.h55
3 files changed, 77 insertions, 62 deletions
diff --git a/src/emu/netlist/nl_setup.c b/src/emu/netlist/nl_setup.c
index e2d2f9835f7..f8f9cf6943f 100644
--- a/src/emu/netlist/nl_setup.c
+++ b/src/emu/netlist/nl_setup.c
@@ -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 &param_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());
diff --git a/src/emu/netlist/nl_setup.h b/src/emu/netlist/nl_setup.h
index 129a6fef001..0bcf9c541ae 100644
--- a/src/emu/netlist/nl_setup.h
+++ b/src/emu/netlist/nl_setup.h
@@ -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,11 +201,24 @@ namespace netlist
private:
+ 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);
+ void connect_terminal_input(terminal_t &term, core_terminal_t &inp);
+ bool connect_input_input(core_terminal_t &t1, core_terminal_t &t2);
+
+ // helpers
+ pstring objtype_as_astr(object_t &in) const;
+
+ 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;
@@ -225,19 +232,6 @@ namespace netlist
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);
- void connect_terminal_input(terminal_t &term, core_terminal_t &inp);
- bool connect_input_input(core_terminal_t &t1, core_terminal_t &t2);
-
- // helpers
- pstring objtype_as_astr(object_t &in) const;
-
- const pstring resolve_alias(const pstring &name) const;
- devices::nld_base_proxy *get_d_a_proxy(core_terminal_t &out);
-
#if 0
template <class T>
void remove_start_with(T &hm, pstring &sw)
diff --git a/src/emu/netlist/plib/plists.h b/src/emu/netlist/plib/plists.h
index 885e80fa32b..669c3f34ad9 100644
--- a/src/emu/netlist/plib/plists.h
+++ b/src/emu/netlist/plib/plists.h
@@ -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;
- }
-#else
+ 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;
+ }
+ 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)