1
0
forked from 0ad/0ad

replace set/map with boost::unordered_* to reduce the number of expensive filesystem::basic_path::operator< calls based on a patch by ortalo (thanks!)

This was SVN commit r8947.
This commit is contained in:
janwas 2011-02-19 21:24:39 +00:00
parent 007985332b
commit 1a2a7677fd
10 changed files with 73 additions and 52 deletions

View File

@ -41,7 +41,7 @@ CSkeletonAnimManager::CSkeletonAnimManager(CColladaManager& colladaManager)
// CSkeletonAnimManager destructor
CSkeletonAnimManager::~CSkeletonAnimManager()
{
typedef std::map<VfsPath,CSkeletonAnimDef*>::iterator Iter;
typedef boost::unordered_map<VfsPath,CSkeletonAnimDef*>::iterator Iter;
for (Iter i = m_Animations.begin(); i != m_Animations.end(); ++i)
delete i->second;
}
@ -54,7 +54,7 @@ CSkeletonAnimDef* CSkeletonAnimManager::GetAnimation(const VfsPath& pathname)
VfsPath name = fs::change_extension(pathname, L"");
// Find if it's already been loaded
std::map<VfsPath, CSkeletonAnimDef*>::iterator iter = m_Animations.find(name);
boost::unordered_map<VfsPath, CSkeletonAnimDef*>::iterator iter = m_Animations.find(name);
if (iter != m_Animations.end())
return iter->second;

View File

@ -25,6 +25,7 @@
#include <map>
#include <set>
#include "lib/file/vfs/vfs_path.h"
#include <boost/unordered_map.hpp>
class CColladaManager;
class CSkeletonAnimDef;
@ -47,7 +48,7 @@ public:
private:
// map of all known animations. Value is NULL if it failed to load.
std::map<VfsPath, CSkeletonAnimDef*> m_Animations;
boost::unordered_map<VfsPath, CSkeletonAnimDef*> m_Animations;
CColladaManager& m_ColladaManager;
};

View File

@ -31,42 +31,44 @@
#include "ps/Filesystem.h"
#include <iomanip>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include <boost/functional/hash.hpp>
// Comparison functor that operates over texture properties, or
// over the properties of a CTexturePtr (ignoring the mutable state like Handle).
struct TextureCacheCmp
struct TPhash
: std::unary_function<CTextureProperties, std::size_t>,
std::unary_function<CTexturePtr, std::size_t>
{
bool operator()(const CTexturePtr& a, const CTexturePtr& b) const
std::size_t operator()(CTextureProperties const& a) const
{
std::size_t seed = 0;
boost::hash_combine(seed, a.m_Path.string());
boost::hash_combine(seed, a.m_Filter);
boost::hash_combine(seed, a.m_Wrap);
boost::hash_combine(seed, a.m_Aniso);
return seed;
}
std::size_t operator()(CTexturePtr const& a) const
{
return (*this)(a->m_Properties);
}
};
struct TPequal_to
: std::binary_function<CTextureProperties, CTextureProperties, bool>,
std::binary_function<CTexturePtr, CTexturePtr, bool>
{
bool operator()(CTextureProperties const& a, CTextureProperties const& b) const
{
return a.m_Path == b.m_Path && a.m_Filter == b.m_Filter
&& a.m_Wrap == b.m_Wrap && a.m_Aniso == b.m_Aniso;
}
bool operator()(CTexturePtr const& a, CTexturePtr const& b) const
{
return (*this)(a->m_Properties, b->m_Properties);
}
bool operator()(const CTextureProperties& a, const CTextureProperties& b) const
{
if (a.m_Path < b.m_Path)
return true;
if (b.m_Path < a.m_Path)
return false;
if (a.m_Filter < b.m_Filter)
return true;
if (b.m_Filter < a.m_Filter)
return false;
if (a.m_Wrap < b.m_Wrap)
return true;
if (b.m_Wrap < a.m_Wrap)
return false;
if (a.m_Aniso < b.m_Aniso)
return true;
if (b.m_Aniso < a.m_Aniso)
return false;
return false;
}
};
class CTextureManagerImpl
{
friend class CTexture;
@ -479,21 +481,20 @@ private:
CTexturePtr m_ErrorTexture;
// Cache of all loaded textures
typedef std::set<CTexturePtr, TextureCacheCmp> TextureCache;
typedef boost::unordered_set<CTexturePtr, TPhash, TPequal_to > TextureCache;
TextureCache m_TextureCache;
// TODO: we ought to expire unused textures from the cache eventually
// Store the set of textures that need to be reloaded when the given file
// (a source file or settings.xml) is modified
typedef std::map<VfsPath, std::set<boost::weak_ptr<CTexture> > > HotloadFilesMap;
typedef boost::unordered_map<VfsPath, std::set<boost::weak_ptr<CTexture> > > HotloadFilesMap;
HotloadFilesMap m_HotloadFiles;
// Cache for the conversion settings files
typedef std::map<VfsPath, shared_ptr<CTextureConverter::SettingsFile> > SettingsFilesMap;
typedef boost::unordered_map<VfsPath, shared_ptr<CTextureConverter::SettingsFile> > SettingsFilesMap;
SettingsFilesMap m_SettingsFiles;
};
CTexture::CTexture(Handle handle, const CTextureProperties& props, CTextureManagerImpl* textureManager) :
m_Handle(handle), m_BaseColour(0), m_State(UNLOADED), m_Properties(props), m_TextureManager(textureManager)
{

View File

@ -121,6 +121,8 @@ class CTextureProperties
{
friend class CTextureManagerImpl;
friend struct TextureCacheCmp;
friend struct TPequal_to;
friend struct TPhash;
public:
/**
@ -180,6 +182,8 @@ class CTexture
{
friend class CTextureManagerImpl;
friend struct TextureCacheCmp;
friend struct TPequal_to;
friend struct TPhash;
// Only the texture manager can create these
explicit CTexture(Handle handle, const CTextureProperties& props, CTextureManagerImpl* textureManager);
@ -187,6 +191,7 @@ class CTexture
NONCOPYABLE(CTexture);
public:
~CTexture();
/**

View File

@ -1035,7 +1035,7 @@ bool CGUI::GetPreDefinedColor(const CStr& name, CColor &Output)
/**
* @callgraph
*/
void CGUI::LoadXmlFile(const VfsPath& Filename, std::set<VfsPath>& Paths)
void CGUI::LoadXmlFile(const VfsPath& Filename, boost::unordered_set<VfsPath>& Paths)
{
Paths.insert(Filename);
@ -1092,7 +1092,7 @@ void CGUI::LoadXmlFile(const VfsPath& Filename, std::set<VfsPath>& Paths)
// XML Reading Xeromyces Specific Sub-Routines
//===================================================================
void CGUI::Xeromyces_ReadRootObjects(XMBElement Element, CXeromyces* pFile, std::set<VfsPath>& Paths)
void CGUI::Xeromyces_ReadRootObjects(XMBElement Element, CXeromyces* pFile, boost::unordered_set<VfsPath>& Paths)
{
int el_script = pFile->GetElementID("script");
@ -1182,7 +1182,7 @@ void CGUI::Xeromyces_ReadRootSetup(XMBElement Element, CXeromyces* pFile)
}
}
void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObject *pParent, const std::vector<std::pair<CStr, CStr> >& NameSubst, std::set<VfsPath>& Paths)
void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObject *pParent, const std::vector<std::pair<CStr, CStr> >& NameSubst, boost::unordered_set<VfsPath>& Paths)
{
debug_assert(pParent);
int i;
@ -1422,7 +1422,7 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec
}
}
void CGUI::Xeromyces_ReadRepeat(XMBElement Element, CXeromyces* pFile, IGUIObject *pParent, std::set<VfsPath>& Paths)
void CGUI::Xeromyces_ReadRepeat(XMBElement Element, CXeromyces* pFile, IGUIObject *pParent, boost::unordered_set<VfsPath>& Paths)
{
#define ELMT(x) int elmt_##x = pFile->GetElementID(#x)
#define ATTR(x) int attr_##x = pFile->GetAttributeID(#x)
@ -1448,7 +1448,7 @@ void CGUI::Xeromyces_ReadRepeat(XMBElement Element, CXeromyces* pFile, IGUIObjec
}
}
void CGUI::Xeromyces_ReadScript(XMBElement Element, CXeromyces* pFile, std::set<VfsPath>& Paths)
void CGUI::Xeromyces_ReadScript(XMBElement Element, CXeromyces* pFile, boost::unordered_set<VfsPath>& Paths)
{
// Check for a 'file' parameter
CStrW file (Element.GetAttributes().GetNamedItem( pFile->GetAttributeID("file") ).FromUTF8());

View File

@ -47,7 +47,7 @@ CGUI
#include "ps/XML/Xeromyces.h"
#include <set>
#include <boost/unordered_set.hpp>
//--------------------------------------------------------
// Macros
@ -182,7 +182,7 @@ public:
* @param Filename Name of file
* @param Paths Set of paths; all XML and JS files loaded will be added to this
*/
void LoadXmlFile(const VfsPath& Filename, std::set<VfsPath>& Paths);
void LoadXmlFile(const VfsPath& Filename, boost::unordered_set<VfsPath>& Paths);
/**
* Checks if object exists and return true or false accordingly
@ -387,7 +387,7 @@ private:
*
* @see LoadXmlFile()
*/
void Xeromyces_ReadRootObjects(XMBElement Element, CXeromyces* pFile, std::set<VfsPath>& Paths);
void Xeromyces_ReadRootObjects(XMBElement Element, CXeromyces* pFile, boost::unordered_set<VfsPath>& Paths);
/**
* Reads in the root element \<sprites\> (the DOMElement).
@ -446,14 +446,14 @@ private:
*
* @see LoadXmlFile()
*/
void Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObject *pParent, const std::vector<std::pair<CStr, CStr> >& NameSubst, std::set<VfsPath>& Paths);
void Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObject *pParent, const std::vector<std::pair<CStr, CStr> >& NameSubst, boost::unordered_set<VfsPath>& Paths);
/**
* Reads in the element \<repeat\>, which repeats its child \<object\>s
* 'count' times, replacing the string "[n]" in its descendants' names
* with "[0]", "[1]", etc.
*/
void Xeromyces_ReadRepeat(XMBElement Element, CXeromyces* pFile, IGUIObject *pParent, std::set<VfsPath>& Paths);
void Xeromyces_ReadRepeat(XMBElement Element, CXeromyces* pFile, IGUIObject *pParent, boost::unordered_set<VfsPath>& Paths);
/**
* Reads in the element \<script\> (the XMBElement) and executes
@ -466,7 +466,7 @@ private:
*
* @see LoadXmlFile()
*/
void Xeromyces_ReadScript(XMBElement Element, CXeromyces* pFile, std::set<VfsPath>& Paths);
void Xeromyces_ReadScript(XMBElement Element, CXeromyces* pFile, boost::unordered_set<VfsPath>& Paths);
/**
* Reads in the element \<sprite\> (the XMBElement) and stores the

View File

@ -18,6 +18,8 @@
#ifndef INCLUDED_GUIMANAGER
#define INCLUDED_GUIMANAGER
#include <boost/unordered_set.hpp>
#include "lib/input.h"
#include "lib/file/vfs/vfs_path.h"
#include "ps/CStr.h"
@ -136,7 +138,7 @@ private:
struct SGUIPage
{
CStrW name;
std::set<VfsPath> inputs; // for hotloading
boost::unordered_set<VfsPath> inputs; // for hotloading
JSContext* cx;
CScriptValRooted initData; // data to be passed to the init() function

View File

@ -32,6 +32,7 @@
#include <list>
#include <map>
#include <queue> // std::priority_queue
#include <boost/unordered_map.hpp>
/*
Cache for items of variable size and value/"cost".
@ -306,10 +307,7 @@ again:
}
protected:
// note: hash_map is probably better in terms of locality
// (relevant when iterating over all items in remove_least_valuable),
// but would require a hash comparator for VfsPath.
class Map : public std::map<Key, Entry>
class Map : public boost::unordered_map<Key, Entry>
{
public:
static Entry& entry_from_it(typename Map::iterator it) { return it->second; }

View File

@ -22,3 +22,13 @@
#include "precompiled.h"
#include "lib/file/vfs/vfs_path.h"
#include <iostream>
#include <string>
std::size_t hash_value(VfsPath const& b)
{
boost::hash<std::wstring> hasher;
return hasher(b.string());
}

View File

@ -23,6 +23,8 @@
#ifndef INCLUDED_VFS_PATH
#define INCLUDED_VFS_PATH
#include <boost/functional/hash.hpp>
struct VfsPathTraits;
/**
@ -43,6 +45,8 @@ typedef fs::basic_path<std::wstring, VfsPathTraits> VfsPath;
typedef std::vector<VfsPath> VfsPaths;
std::size_t hash_value(VfsPath const& b);
struct VfsPathTraits
{
typedef std::wstring internal_string_type;