tagged_list without tagmap_t (nw)

This commit is contained in:
Miodrag Milanovic 2015-12-11 13:59:37 +01:00
parent e883c98c93
commit 9a2ed1703a
5 changed files with 7 additions and 316 deletions

View File

@ -86,7 +86,6 @@ project "utils"
MAME_DIR .. "src/lib/util/pool.h",
MAME_DIR .. "src/lib/util/sha1.cpp",
MAME_DIR .. "src/lib/util/sha1.h",
MAME_DIR .. "src/lib/util/tagmap.cpp",
MAME_DIR .. "src/lib/util/tagmap.h",
MAME_DIR .. "src/lib/util/unicode.cpp",
MAME_DIR .. "src/lib/util/unicode.h",

View File

@ -354,11 +354,6 @@ int running_machine::run(bool firstrun)
// perform a soft reset -- this takes us to the running phase
soft_reset();
#ifdef MAME_DEBUG
g_tagmap_finds = 0;
if (strcmp(config().m_gamedrv.name, "___empty") != 0)
g_tagmap_counter_enabled = true;
#endif
// handle initial load
if (m_saveload_schedule != SLS_NONE)
handle_saveload();
@ -392,15 +387,6 @@ int running_machine::run(bool firstrun)
// and out via the exit phase
m_current_phase = MACHINE_PHASE_EXIT;
#ifdef MAME_DEBUG
if (g_tagmap_counter_enabled)
{
g_tagmap_counter_enabled = false;
if (*(options().command()) == 0)
osd_printf_info("%d tagmap lookups\n", g_tagmap_finds);
}
#endif
// save the NVRAM and configuration
sound().ui_mute(true);
nvram_save();
@ -443,15 +429,6 @@ int running_machine::run(bool firstrun)
// in case we got here via exception
m_current_phase = MACHINE_PHASE_EXIT;
#ifdef MAME_DEBUG
if (g_tagmap_counter_enabled)
{
g_tagmap_counter_enabled = false;
if (*(options().command()) == 0)
osd_printf_info("%d tagmap lookups\n", g_tagmap_finds);
}
#endif
// call all exit callbacks registered
call_notifiers(MACHINE_NOTIFY_EXIT);
zip_file_cache_clear();
@ -473,15 +450,6 @@ void running_machine::schedule_exit()
// if we're executing, abort out immediately
m_scheduler.eat_all_cycles();
#ifdef MAME_DEBUG
if (g_tagmap_counter_enabled)
{
g_tagmap_counter_enabled = false;
if (*(options().command()) == 0)
osd_printf_info("%d tagmap lookups\n", g_tagmap_finds);
}
#endif
// if we're autosaving on exit, schedule a save as well
if (options().autosave() && (m_system.flags & MACHINE_SUPPORTS_SAVE) && this->time() > attotime::zero)
schedule_save("auto");

View File

@ -1037,15 +1037,6 @@ void video_manager::recompute_speed(const attotime &emutime)
// if we're past the "time-to-execute" requested, signal an exit
if (m_seconds_to_run != 0 && emutime.seconds() >= m_seconds_to_run)
{
#ifdef MAME_DEBUG
if (g_tagmap_counter_enabled)
{
g_tagmap_counter_enabled = false;
if (*(machine().options().command()) == 0)
osd_printf_info("%d tagmap lookups\n", g_tagmap_finds);
}
#endif
if (machine().first_screen() != nullptr)
{
// create a final screenshot

View File

@ -1,20 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
tagmap.c
tagmap counter
***************************************************************************/
#include <assert.h>
#include "tagmap.h"
#ifdef MAME_DEBUG
/** @brief The tagmap finds. */
INT32 g_tagmap_finds = 0;
/** @brief true to enable, false to disable the tagmap counter. */
bool g_tagmap_counter_enabled = false;
#endif

View File

@ -17,11 +17,7 @@
#include "coretmpl.h"
#include <string>
#include <utility>
#ifdef MAME_DEBUG
#include "eminline.h"
#endif
#include <unordered_map>
//**************************************************************************
// CONSTANTS
@ -33,169 +29,6 @@ enum tagmap_error
TMERR_DUPLICATE
};
#ifdef MAME_DEBUG
extern INT32 g_tagmap_finds;
extern bool g_tagmap_counter_enabled;
#endif
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// generally used for small tables, though the hash size can be increased
// as necessary; good primes are: 53, 97, 193, 389, 769, 1543, 3079, 6151, etc
template<class _ElementType, int _HashSize = 53>
class tagmap_t
{
private:
// disable copying/assignment
tagmap_t(const tagmap_t &);
tagmap_t &operator=(const tagmap_t &);
public:
// an entry in the table
class entry_t
{
friend class tagmap_t<_ElementType, _HashSize>;
public:
// construction/destruction
entry_t(const char *tag, UINT32 fullhash, _ElementType object)
: m_next(nullptr),
m_fullhash(fullhash),
m_tag(tag),
m_object(std::move(object)) { }
// accessors
const std::string &tag() const { return m_tag; }
_ElementType object() const { return m_object; }
// setters
void set_object(_ElementType object) { m_object = object; }
private:
// internal helpers
entry_t *next() const { return m_next; }
UINT32 fullhash() const { return m_fullhash; }
// internal state
entry_t * m_next;
UINT32 m_fullhash;
std::string m_tag;
_ElementType m_object;
};
// construction/destruction
tagmap_t() { memset(m_table, 0, sizeof(m_table)); }
~tagmap_t() { reset(); }
// core hashing function
UINT32 hash(const char *string) const
{
UINT32 result = *string++;
for (UINT8 c = *string++; c != 0; c = *string++)
result = (result*33) ^ c;
return result;
}
// empty the list
void reset()
{
for (auto & elem : m_table)
while (elem != nullptr)
remove_common(&elem);
}
// add/remove
tagmap_error add(const char *tag, _ElementType object, bool replace_if_duplicate = false) { return add_common(tag, object, replace_if_duplicate, false); }
tagmap_error add_unique_hash(const char *tag, _ElementType object, bool replace_if_duplicate = false) { return add_common(tag, object, replace_if_duplicate, true); }
// remove by tag
void remove(const char *tag)
{
UINT32 fullhash = hash(tag);
for (entry_t **entryptr = &m_table[fullhash % ARRAY_LENGTH(m_table)]; *entryptr != nullptr; entryptr = &(*entryptr)->m_next)
if ((*entryptr)->fullhash() == fullhash && (*entryptr)->tag() == tag)
return remove_common(entryptr);
}
// remove by object
void remove(_ElementType object)
{
for (auto & elem : m_table)
for (entry_t **entryptr = &elem; *entryptr != nullptr; entryptr = &(*entryptr)->m_next)
if ((*entryptr)->object() == object)
return remove_common(entryptr);
}
// find by tag
_ElementType find(const char *tag) const { return find(tag, hash(tag)); }
// find by tag with precomputed hash
_ElementType find(const char *tag, UINT32 fullhash) const
{
#ifdef MAME_DEBUG
if (g_tagmap_counter_enabled)
atomic_increment32(&g_tagmap_finds);
#endif
for (entry_t *entry = m_table[fullhash % ARRAY_LENGTH(m_table)]; entry != nullptr; entry = entry->next())
if (entry->fullhash() == fullhash && entry->tag() == tag)
return entry->object();
return _ElementType(NULL);
}
// find by tag without checking anything but the hash
_ElementType find_hash_only(const char *tag) const
{
#ifdef MAME_DEBUG
if (g_tagmap_counter_enabled)
atomic_increment32(&g_tagmap_finds);
#endif
UINT32 fullhash = hash(tag);
for (entry_t *entry = m_table[fullhash % ARRAY_LENGTH(m_table)]; entry != nullptr; entry = entry->next())
if (entry->fullhash() == fullhash)
return entry->object();
return nullptr;
}
// return first object in the table
entry_t *first() const { return next(NULL); }
// return next object in the table
entry_t *next(entry_t *after) const
{
// if there's another item in this hash bucket, just return it
if (after != NULL && after->next() != NULL)
return after->next();
// otherwise scan forward for the next bucket with an entry
UINT32 firstindex = (after != NULL) ? (after->fullhash() % ARRAY_LENGTH(m_table) + 1) : 0;
for (UINT32 hashindex = firstindex; hashindex < ARRAY_LENGTH(m_table); hashindex++)
if (m_table[hashindex] != NULL)
return m_table[hashindex];
// all out
return NULL;
}
private:
// internal helpers
tagmap_error add_common(const char *tag, _ElementType object, bool replace_if_duplicate, bool unique_hash);
// remove an entry given a pointer to its pointer
void remove_common(entry_t **entryptr)
{
entry_t *entry = *entryptr;
*entryptr = entry->next();
global_free(entry);
}
// internal state
entry_t * m_table[_HashSize];
};
// ======================> tagged_list
class add_exception
@ -225,12 +58,12 @@ public:
int count() const { return m_list.count(); }
// remove (free) all objects in the list, leaving an empty list
void reset() { m_list.reset(); m_map.reset(); }
void reset() { m_list.reset(); m_map.clear(); }
// add the given object to the head of the list
_ElementType &prepend(const char *tag, _ElementType &object)
{
if (m_map.add_unique_hash(tag, &object, false) != TMERR_NONE)
if (!m_map.insert(std::make_pair(tag, &object)).second)
throw add_exception(tag);
return m_list.prepend(object);
}
@ -238,100 +71,20 @@ public:
// add the given object to the tail of the list
_ElementType &append(const char *tag, _ElementType &object)
{
if (m_map.add_unique_hash(tag, &object, false) != TMERR_NONE)
if (!m_map.insert(std::make_pair(tag, &object)).second)
throw add_exception(tag);
return m_list.append(object);
}
// insert the given object after a particular object (NULL means prepend)
_ElementType &insert_after(const char *tag, _ElementType &object, _ElementType *insert_after)
{
if (m_map.add_unique_hash(tag, &object, false) != TMERR_NONE)
throw add_exception(tag);
return m_list.insert_after(object, insert_after);
}
// replace an item in the list at the same location, and remove it
_ElementType &replace_and_remove(const char *tag, _ElementType &object, _ElementType &toreplace)
{
m_map.remove(&toreplace);
m_list.replace_and_remove(object, toreplace);
if (m_map.add_unique_hash(tag, &object, false) != TMERR_NONE)
throw add_exception(tag);
return object;
}
// detach the given item from the list, but don't free its memory
_ElementType &detach(_ElementType &object)
{
m_map.remove(&object);
return m_list.detach(object);
}
// remove the given object and free its memory
void remove(_ElementType &object)
{
m_map.remove(&object);
return m_list.remove(object);
}
// find an object by index in the list
_ElementType *find(int index) const
{
return m_list.find(index);
}
// return the index of the given object in the list
int indexof(const _ElementType &object) const
{
return m_list.indexof(object);
}
// operations by tag
_ElementType &replace_and_remove(const char *tag, _ElementType &object) { _ElementType *existing = find(tag); return (existing == NULL) ? append(tag, object) : replace_and_remove(tag, object, *existing); }
void remove(const char *tag) { _ElementType *object = find(tag); if (object != nullptr) remove(*object); }
_ElementType *find(const char *tag) const { return m_map.find_hash_only(tag); }
int indexof(const char *tag) const { _ElementType *object = find(tag); return (object != NULL) ? m_list.indexof(*object) : NULL; }
void remove(const char *tag) { auto search = m_map.find(tag); if (search != m_map.end()) m_list.remove(*search->second); }
_ElementType *find(const char *tag) const { auto search = m_map.find(tag); return (search == m_map.end()) ? nullptr : search->second; }
private:
// internal state
simple_list<_ElementType> m_list;
tagmap_t<_ElementType *> m_map;
std::unordered_map<std::string,_ElementType *> m_map;
};
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
//-------------------------------------------------
// add_common - core implementation of a tagmap
// addition
//-------------------------------------------------
template<class _ElementType, int _HashSize>
tagmap_error tagmap_t<_ElementType, _HashSize>::add_common(const char *tag, _ElementType object, bool replace_if_duplicate, bool unique_hash)
{
UINT32 fullhash = hash(tag);
UINT32 hashindex = fullhash % ARRAY_LENGTH(m_table);
// first make sure we don't have a duplicate
for (entry_t *entry = m_table[hashindex]; entry != nullptr; entry = entry->next())
if (entry->fullhash() == fullhash)
if (unique_hash || entry->tag() == tag)
{
if (replace_if_duplicate)
entry->set_object(object);
return TMERR_DUPLICATE;
}
// now allocate a new entry and add to the head of the list
auto entry = global_alloc(entry_t(tag, fullhash, object));
entry->m_next = m_table[hashindex];
m_table[hashindex] = entry;
return TMERR_NONE;
}
#endif /* __TAGMAP_H__ */