mirror of
https://github.com/holub/mame
synced 2025-07-04 09:28:51 +03:00
Added a phashmap_t object for faster lookups. (nw)
This commit is contained in:
parent
f6ea498ecf
commit
1c9b70aabd
@ -136,27 +136,6 @@ device_t *setup_t::register_dev(const pstring &classname, const pstring &name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_t::remove_dev(const pstring &name)
|
|
||||||
{
|
|
||||||
device_t *dev = netlist().m_devices.find_by_name(name);
|
|
||||||
pstring temp = name + ".";
|
|
||||||
if (dev == NULL)
|
|
||||||
netlist().error("Device %s does not exist\n", name.cstr());
|
|
||||||
|
|
||||||
remove_start_with<tagmap_terminal_t>(m_terminals, temp);
|
|
||||||
remove_start_with<tagmap_param_t>(m_params, temp);
|
|
||||||
|
|
||||||
const link_t *p = m_links.data();
|
|
||||||
while (p != NULL)
|
|
||||||
{
|
|
||||||
const link_t *n = p+1;
|
|
||||||
if (temp.equals(p->e1.substr(0,temp.len())) || temp.equals(p->e2.substr(0,temp.len())))
|
|
||||||
m_links.remove(*p);
|
|
||||||
p = n;
|
|
||||||
}
|
|
||||||
netlist().m_devices.remove_by_name(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup_t::register_model(const pstring &model)
|
void setup_t::register_model(const pstring &model)
|
||||||
{
|
{
|
||||||
m_models.add(model);
|
m_models.add(model);
|
||||||
@ -164,7 +143,7 @@ void setup_t::register_model(const pstring &model)
|
|||||||
|
|
||||||
void setup_t::register_alias_nofqn(const pstring &alias, const pstring &out)
|
void setup_t::register_alias_nofqn(const pstring &alias, const pstring &out)
|
||||||
{
|
{
|
||||||
if (!(m_alias.add(link_t(alias, out), false)==true))
|
if (!m_alias.add(alias, out))
|
||||||
netlist().error("Error adding alias %s to alias list\n", alias.cstr());
|
netlist().error("Error adding alias %s to alias list\n", alias.cstr());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,9 +245,9 @@ void setup_t::register_object(device_t &dev, const pstring &name, object_t &obj)
|
|||||||
{
|
{
|
||||||
param_t ¶m = dynamic_cast<param_t &>(obj);
|
param_t ¶m = dynamic_cast<param_t &>(obj);
|
||||||
//printf("name: %s\n", name.cstr());
|
//printf("name: %s\n", name.cstr());
|
||||||
const pstring val = m_params_temp.find_by_name(name).e2;
|
if (m_params_temp.contains(name))
|
||||||
if (val != "")
|
|
||||||
{
|
{
|
||||||
|
const pstring val = m_params_temp[name];
|
||||||
switch (param.param_type())
|
switch (param.param_type())
|
||||||
{
|
{
|
||||||
case param_t::DOUBLE:
|
case param_t::DOUBLE:
|
||||||
@ -302,7 +281,7 @@ void setup_t::register_object(device_t &dev, const pstring &name, object_t &obj)
|
|||||||
netlist().error("Parameter is not supported %s : %s\n", name.cstr(), val.cstr());
|
netlist().error("Parameter is not supported %s : %s\n", name.cstr(), val.cstr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(m_params.add(¶m, false)==true))
|
if (!m_params.add(param.name(), ¶m))
|
||||||
netlist().error("Error adding parameter %s to parameter list\n", name.cstr());
|
netlist().error("Error adding parameter %s to parameter list\n", name.cstr());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -400,16 +379,16 @@ void setup_t::register_param(const pstring ¶m, const pstring &value)
|
|||||||
{
|
{
|
||||||
pstring fqn = build_fqn(param);
|
pstring fqn = build_fqn(param);
|
||||||
|
|
||||||
int idx = m_params_temp.index_by_name(fqn);
|
int idx = m_params_temp.index_of(fqn);
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
{
|
{
|
||||||
if (!(m_params_temp.add(link_t(fqn, value), false)==true))
|
if (!m_params_temp.add(fqn, value))
|
||||||
netlist().error("Unexpected error adding parameter %s to parameter list\n", param.cstr());
|
netlist().error("Unexpected error adding parameter %s to parameter list\n", param.cstr());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
netlist().warning("Overwriting %s old <%s> new <%s>\n", fqn.cstr(), m_params_temp[idx].e2.cstr(), value.cstr());
|
netlist().warning("Overwriting %s old <%s> new <%s>\n", fqn.cstr(), m_params_temp.value_at(idx).cstr(), value.cstr());
|
||||||
m_params_temp[idx].e2 = value;
|
m_params_temp[fqn] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,7 +400,8 @@ const pstring setup_t::resolve_alias(const pstring &name) const
|
|||||||
/* FIXME: Detect endless loop */
|
/* FIXME: Detect endless loop */
|
||||||
do {
|
do {
|
||||||
ret = temp;
|
ret = temp;
|
||||||
temp = m_alias.find_by_name(ret).e2;
|
int p = m_alias.index_of(ret);
|
||||||
|
temp = (p>=0 ? m_alias.value_at(p) : "");
|
||||||
} while (temp != "");
|
} while (temp != "");
|
||||||
|
|
||||||
NL_VERBOSE_OUT(("%s==>%s\n", name.cstr(), ret.cstr()));
|
NL_VERBOSE_OUT(("%s==>%s\n", name.cstr(), ret.cstr()));
|
||||||
@ -480,14 +460,14 @@ param_t *setup_t::find_param(const pstring ¶m_in, bool required)
|
|||||||
const pstring param_in_fqn = build_fqn(param_in);
|
const pstring param_in_fqn = build_fqn(param_in);
|
||||||
|
|
||||||
const pstring &outname = resolve_alias(param_in_fqn);
|
const pstring &outname = resolve_alias(param_in_fqn);
|
||||||
param_t *ret;
|
int ret;
|
||||||
|
|
||||||
ret = m_params.find_by_name(outname);
|
ret = m_params.index_of(outname);
|
||||||
if (ret == NULL && required)
|
if (ret < 0 && required)
|
||||||
netlist().error("parameter %s(%s) not found!\n", param_in_fqn.cstr(), outname.cstr());
|
netlist().error("parameter %s(%s) not found!\n", param_in_fqn.cstr(), outname.cstr());
|
||||||
if (ret != NULL)
|
if (ret != -1)
|
||||||
NL_VERBOSE_OUT(("Found parameter %s\n", outname.cstr()));
|
NL_VERBOSE_OUT(("Found parameter %s\n", outname.cstr()));
|
||||||
return ret;
|
return (ret == -1 ? NULL : m_params.value_at(ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME avoid dynamic cast here
|
// FIXME avoid dynamic cast here
|
||||||
|
@ -32,9 +32,6 @@
|
|||||||
#define NET_REGISTER_DEV_X(_type, _name) \
|
#define NET_REGISTER_DEV_X(_type, _name) \
|
||||||
setup.register_dev(# _type, # _name);
|
setup.register_dev(# _type, # _name);
|
||||||
|
|
||||||
#define NET_REMOVE_DEV(_name) \
|
|
||||||
setup.remove_dev(# _name);
|
|
||||||
|
|
||||||
#define NET_REGISTER_SIGNAL(_type, _name) \
|
#define NET_REGISTER_SIGNAL(_type, _name) \
|
||||||
NET_REGISTER_DEV(_type ## _ ## sig, _name)
|
NET_REGISTER_DEV(_type ## _ ## sig, _name)
|
||||||
|
|
||||||
@ -133,10 +130,8 @@ namespace netlist
|
|||||||
const pstring &name() const { return e1; }
|
const pstring &name() const { return e1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef pnamedlist_t<link_t> tagmap_nstring_t;
|
//typedef pnamedlist_t<link_t> tagmap_nstring_t;
|
||||||
typedef pnamedlist_t<param_t *> tagmap_param_t;
|
|
||||||
typedef pnamedlist_t<core_terminal_t *> tagmap_terminal_t;
|
typedef pnamedlist_t<core_terminal_t *> tagmap_terminal_t;
|
||||||
typedef plist_t<link_t> tagmap_link_t;
|
|
||||||
|
|
||||||
setup_t(netlist_t *netlist);
|
setup_t(netlist_t *netlist);
|
||||||
~setup_t();
|
~setup_t();
|
||||||
@ -217,10 +212,11 @@ namespace netlist
|
|||||||
|
|
||||||
netlist_t *m_netlist;
|
netlist_t *m_netlist;
|
||||||
|
|
||||||
tagmap_nstring_t m_alias;
|
phashmap_t<pstring, pstring> m_alias;
|
||||||
tagmap_param_t m_params;
|
phashmap_t<pstring, param_t *> m_params;
|
||||||
tagmap_link_t m_links;
|
phashmap_t<pstring, pstring> m_params_temp;
|
||||||
tagmap_nstring_t m_params_temp;
|
|
||||||
|
plist_t<link_t> m_links;
|
||||||
|
|
||||||
factory_list_t *m_factory;
|
factory_list_t *m_factory;
|
||||||
|
|
||||||
@ -245,6 +241,7 @@ namespace netlist
|
|||||||
const pstring resolve_alias(const pstring &name) const;
|
const pstring resolve_alias(const pstring &name) const;
|
||||||
devices::nld_base_proxy *get_d_a_proxy(core_terminal_t &out);
|
devices::nld_base_proxy *get_d_a_proxy(core_terminal_t &out);
|
||||||
|
|
||||||
|
#if 0
|
||||||
template <class T>
|
template <class T>
|
||||||
void remove_start_with(T &hm, pstring &sw)
|
void remove_start_with(T &hm, pstring &sw)
|
||||||
{
|
{
|
||||||
@ -258,6 +255,7 @@ namespace netlist
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
@ -606,6 +606,146 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------------------
|
||||||
|
// hashmap list
|
||||||
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
template <class C>
|
||||||
|
struct phash_functor
|
||||||
|
{
|
||||||
|
unsigned hash(const C &v) { return (unsigned) v; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct phash_functor<pstring>
|
||||||
|
{
|
||||||
|
unsigned hash(const pstring &v)
|
||||||
|
{
|
||||||
|
const char *string = v.cstr();
|
||||||
|
unsigned result = *string++;
|
||||||
|
for (UINT8 c = *string++; c != 0; c = *string++)
|
||||||
|
result = (result*33) ^ c;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* some primes 53, 97, 193, 389, 769, 1543, 3079, 6151 */
|
||||||
|
template <class K, class V, class H = phash_functor<K> >
|
||||||
|
class phashmap_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
phashmap_t() : m_hash(389)
|
||||||
|
{
|
||||||
|
for (unsigned i=0; i<m_hash.size(); i++)
|
||||||
|
m_hash[i] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct element_t
|
||||||
|
{
|
||||||
|
element_t() { }
|
||||||
|
element_t(K key, unsigned hash, V value)
|
||||||
|
: m_key(key), m_hash(hash), m_value(value), m_next(-1)
|
||||||
|
{}
|
||||||
|
K m_key;
|
||||||
|
unsigned m_hash;
|
||||||
|
V m_value;
|
||||||
|
int m_next;
|
||||||
|
};
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
m_values.clear();
|
||||||
|
for (unsigned i=0; i<m_hash.size(); i++)
|
||||||
|
m_hash[i] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains(const K &key) const
|
||||||
|
{
|
||||||
|
return (get_idx(key) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int index_of(const K &key) const
|
||||||
|
{
|
||||||
|
return get_idx(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned size() const { return m_values.size(); }
|
||||||
|
|
||||||
|
bool add(const K &key, const V &value)
|
||||||
|
{
|
||||||
|
H h;
|
||||||
|
const unsigned hash=h.hash(key);
|
||||||
|
const unsigned pos = hash % m_hash.size();
|
||||||
|
if (m_hash[pos] == -1)
|
||||||
|
{
|
||||||
|
unsigned vpos = m_values.size();
|
||||||
|
m_values.add(element_t(key, hash, value));
|
||||||
|
m_hash[pos] = vpos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int ep = m_hash[pos];
|
||||||
|
|
||||||
|
for (; ep != -1; ep = m_values[ep].m_next)
|
||||||
|
{
|
||||||
|
if (m_values[ep].m_hash == hash && m_values[ep].m_key == key )
|
||||||
|
return false; /* duplicate */
|
||||||
|
}
|
||||||
|
unsigned vpos = m_values.size();
|
||||||
|
m_values.add(element_t(key, hash, value));
|
||||||
|
m_values[vpos].m_next = m_hash[pos];
|
||||||
|
m_hash[pos] = vpos;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
V& operator[](const K &key)
|
||||||
|
{
|
||||||
|
int p = get_idx(key);
|
||||||
|
if (p == -1)
|
||||||
|
{
|
||||||
|
p = m_values.size();
|
||||||
|
add(key, V());
|
||||||
|
}
|
||||||
|
return m_values[p].m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const V& operator[](const K &key) const
|
||||||
|
{
|
||||||
|
int p = get_idx(key);
|
||||||
|
if (p == -1)
|
||||||
|
{
|
||||||
|
p = m_values.size();
|
||||||
|
add(key, V());
|
||||||
|
}
|
||||||
|
return m_values[p].m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
V& value_at(const unsigned pos) { return m_values[pos].m_value; }
|
||||||
|
const V& value_at(const unsigned pos) const { return m_values[pos].m_value; }
|
||||||
|
|
||||||
|
V& key_at(const unsigned pos) const { return m_values[pos].m_key; }
|
||||||
|
private:
|
||||||
|
|
||||||
|
int get_idx(const K &key) const
|
||||||
|
{
|
||||||
|
H h;
|
||||||
|
const unsigned hash=h.hash(key);
|
||||||
|
const unsigned pos = hash % m_hash.size();
|
||||||
|
|
||||||
|
for (int ep = m_hash[pos]; ep != -1; ep = m_values[ep].m_next)
|
||||||
|
{
|
||||||
|
if (m_values[ep].m_hash == hash && m_values[ep].m_key == key )
|
||||||
|
return ep;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
plist_t<element_t> m_values;
|
||||||
|
parray_t<int> m_hash;
|
||||||
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
// sort a list ... slow, I am lazy
|
// sort a list ... slow, I am lazy
|
||||||
// elements must support ">" operator.
|
// elements must support ">" operator.
|
||||||
|
@ -75,3 +75,4 @@ template<> ATTR_COLD void pstate_manager_t::save_item(pstate_callback_t &state,
|
|||||||
m_save.add(p);
|
m_save.add(p);
|
||||||
state.register_state(*this, stname);
|
state.register_state(*this, stname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user