Optimize CNodeDefManager::getIds

This commit is contained in:
kwolekr 2013-03-30 19:12:23 -04:00
parent 02d8df94a8
commit 414f0275cf
2 changed files with 39 additions and 0 deletions

@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h" #include "settings.h"
#include "nameidmapping.h" #include "nameidmapping.h"
#include "util/serialize.h" #include "util/serialize.h"
//#include "profiler.h" // For TimeTaker
/* /*
NodeBox NodeBox
@ -452,6 +453,7 @@ public:
virtual void getIds(const std::string &name, std::set<content_t> &result) virtual void getIds(const std::string &name, std::set<content_t> &result)
const const
{ {
//TimeTaker t("getIds", NULL, PRECISION_MICRO);
if(name.substr(0,6) != "group:"){ if(name.substr(0,6) != "group:"){
content_t id = CONTENT_IGNORE; content_t id = CONTENT_IGNORE;
if(getId(name, id)) if(getId(name, id))
@ -459,6 +461,20 @@ public:
return; return;
} }
std::string group = name.substr(6); std::string group = name.substr(6);
#if 1 // Optimized version, takes less than 1 microsecond at -O1
std::map<std::string, GroupItems>::const_iterator
i = m_group_to_items.find(group);
if (i == m_group_to_items.end())
return;
const GroupItems &items = i->second;
for (GroupItems::const_iterator j = items.begin();
j != items.end(); ++j) {
if ((*j).second != 0)
result.insert((*j).first);
}
#else // Old version, takes about ~150-200us at -O1
for(u16 id=0; id<=MAX_CONTENT; id++) for(u16 id=0; id<=MAX_CONTENT; id++)
{ {
const ContentFeatures &f = m_content_features[id]; const ContentFeatures &f = m_content_features[id];
@ -467,6 +483,8 @@ public:
if(itemgroup_get(f.groups, group) != 0) if(itemgroup_get(f.groups, group) != 0)
result.insert(id); result.insert(id);
} }
#endif
//printf("getIds: %dus\n", t.stop());
} }
virtual const ContentFeatures& get(const std::string &name) const virtual const ContentFeatures& get(const std::string &name) const
{ {
@ -498,6 +516,21 @@ public:
m_content_features[c] = def; m_content_features[c] = def;
if(def.name != "") if(def.name != "")
addNameIdMapping(c, def.name); addNameIdMapping(c, def.name);
// Add this content to the list of all groups it belongs to
for (ItemGroupList::const_iterator i = def.groups.begin();
i != def.groups.end(); ++i) {
std::string group_name = i->first;
std::map<std::string, GroupItems>::iterator
j = m_group_to_items.find(group_name);
if (j == m_group_to_items.end()) {
m_group_to_items[group_name].push_back(std::make_pair(c, i->second));
} else {
GroupItems &items = j->second;
items.push_back(std::make_pair(c, i->second));
}
}
} }
virtual content_t set(const std::string &name, virtual content_t set(const std::string &name,
const ContentFeatures &def) const ContentFeatures &def)
@ -787,6 +820,9 @@ private:
// item aliases too. Updated by updateAliases() // item aliases too. Updated by updateAliases()
// Note: Not serialized. // Note: Not serialized.
std::map<std::string, content_t> m_name_id_mapping_with_aliases; std::map<std::string, content_t> m_name_id_mapping_with_aliases;
// A mapping from groups to a list of content_ts (and their levels)
// that belong to it. Necessary for a direct lookup in getIds().
std::map<std::string, GroupItems> m_group_to_items;
}; };
IWritableNodeDefManager* createNodeDefManager() IWritableNodeDefManager* createNodeDefManager()

@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <list>
#include "mapnode.h" #include "mapnode.h"
#ifndef SERVER #ifndef SERVER
#include "tile.h" #include "tile.h"
@ -36,6 +37,8 @@ class IItemDefManager;
class ITextureSource; class ITextureSource;
class IGameDef; class IGameDef;
typedef std::list<std::pair<content_t, int> > GroupItems;
enum ContentParamType enum ContentParamType
{ {
CPT_NONE, CPT_NONE,