Pārlūkot izejas kodu

* improved speed of CLodHandler::entries

mateuszb 14 gadi atpakaļ
vecāks
revīzija
9e3f8b86bf
3 mainītis faili ar 30 papildinājumiem un 22 dzēšanām
  1. 7 1
      global.h
  2. 8 13
      lib/CLodHandler.cpp
  3. 15 8
      lib/CLodHandler.h

+ 7 - 1
global.h

@@ -5,6 +5,7 @@
 #include <algorithm> //std::find
 #include <algorithm> //std::find
 #include <string> //std::find
 #include <string> //std::find
 #include <boost/logic/tribool.hpp>
 #include <boost/logic/tribool.hpp>
+#include <boost/unordered_set.hpp>
 using boost::logic::tribool;
 using boost::logic::tribool;
 #include <boost/cstdint.hpp>
 #include <boost/cstdint.hpp>
 #include <assert.h>
 #include <assert.h>
@@ -400,7 +401,12 @@ namespace vstd
 		return c.find(i)!=c.end();
 		return c.find(i)!=c.end();
 	}
 	}
 	template <typename V, typename Item, typename Item2>
 	template <typename V, typename Item, typename Item2>
-	bool contains(const bmap<Item,V> & c, const Item2 &i) //returns true if map c contains item i
+	bool contains(const bmap<Item,V> & c, const Item2 &i) //returns true if bmap c contains item i
+	{
+		return c.find(i)!=c.end();
+	}
+	template <typename Item>
+	bool contains(const boost::unordered_set<Item> & c, const Item &i) //returns true if unordered set c contains item i
 	{
 	{
 		return c.find(i)!=c.end();
 		return c.find(i)!=c.end();
 	}
 	}

+ 8 - 13
lib/CLodHandler.cpp

@@ -60,16 +60,6 @@ std::string readString(const unsigned char * bufor, int &i)
 	return ret;
 	return ret;
 }
 }
 
 
-Entry CLodHandler::getEntry(const std::string name, LodFileType type)
-{
-	Entry ret;
-	std::set<Entry>::iterator it = entries.find(Entry(name, type));
-	
-	if (it!=entries.end())
-		ret = *it;
-	return ret;
-}
-
 unsigned char * CLodHandler::giveFile(const std::string defName, LodFileType type, int * length)
 unsigned char * CLodHandler::giveFile(const std::string defName, LodFileType type, int * length)
 {
 {
 	std::string fname = defName;
 	std::string fname = defName;
@@ -77,13 +67,18 @@ unsigned char * CLodHandler::giveFile(const std::string defName, LodFileType typ
 	int dotPos = fname.find_last_of('.');
 	int dotPos = fname.find_last_of('.');
 	if ( dotPos != -1 )
 	if ( dotPos != -1 )
 		fname.erase(dotPos);
 		fname.erase(dotPos);
-		
-	Entry ourEntry = getEntry(fname, type);
-	if(!vstd::contains(entries, ourEntry)) //nothing's been found
+
+	int count = entries.size();
+
+	boost::unordered_set<Entry>::const_iterator en_it = entries.find(Entry(fname, type));
+	
+	if(en_it == entries.end()) //nothing's been found
 	{
 	{
 		tlog1 << "Cannot find file: " << fname << std::endl;
 		tlog1 << "Cannot find file: " << fname << std::endl;
 		return NULL;
 		return NULL;
 	}
 	}
+	Entry ourEntry = *en_it;
+
 	if(length) *length = ourEntry.realSize;
 	if(length) *length = ourEntry.realSize;
 	mutex->lock();
 	mutex->lock();
 
 

+ 15 - 8
lib/CLodHandler.h

@@ -6,6 +6,7 @@
 #include <fstream>
 #include <fstream>
 #include <set>
 #include <set>
 #include <map>
 #include <map>
+#include <boost/unordered_set.hpp>
 
 
 /*
 /*
  * CLodhandler.h, part of VCMI engine
  * CLodhandler.h, part of VCMI engine
@@ -52,6 +53,7 @@ enum LodFileType{
 	FILE_OTHER
 	FILE_OTHER
 };
 };
 
 
+
 struct Entry
 struct Entry
 {
 {
 	// Info extracted from LOD file
 	// Info extracted from LOD file
@@ -62,12 +64,6 @@ struct Entry
 		size;	//and with
 		size;	//and with
 	LodFileType type;// file type determined by extension
 	LodFileType type;// file type determined by extension
 
 
-	bool operator<(const Entry & comp) const
-	{
-		return type==comp.type ? name<comp.name
-		                       : type<comp.type;
-	}
-	
 	bool operator == (const Entry & comp) const
 	bool operator == (const Entry & comp) const
 	{
 	{
 		return (type==comp.type || comp.type== FILE_ANY) && name==comp.name;
 		return (type==comp.type || comp.type== FILE_ANY) && name==comp.name;
@@ -78,6 +74,18 @@ struct Entry
 	Entry(){};
 	Entry(){};
 };
 };
 
 
+template<>
+struct boost::hash<Entry> : public std::unary_function<Entry, std::size_t> {
+private:
+	boost::hash<std::string> stringHasher;
+public:
+	std::size_t operator()(Entry const& en) const
+	{
+		//do NOT improve this hash function as we need same-name hash collisions for find to work properly
+		return stringHasher(en.name);
+	}
+};
+
 class DLL_EXPORT CLodHandler
 class DLL_EXPORT CLodHandler
 {
 {
 	std::map<std::string, LodFileType> extMap;// to convert extensions to file type
 	std::map<std::string, LodFileType> extMap;// to convert extensions to file type
@@ -88,12 +96,11 @@ class DLL_EXPORT CLodHandler
 	std::string myDir; //load files from this dir instead of .lod file
 	std::string myDir; //load files from this dir instead of .lod file
 
 
 	void initEntry(Entry &e, const std::string name);
 	void initEntry(Entry &e, const std::string name);
-	Entry getEntry(const std::string name, LodFileType);
 	int infs2(unsigned char * in, int size, int realSize, unsigned char*& out, int wBits=15); //zlib fast handler
 	int infs2(unsigned char * in, int size, int realSize, unsigned char*& out, int wBits=15); //zlib fast handler
 
 
 public:
 public:
 
 
-	std::set<Entry> entries;
+	boost::unordered_set<Entry> entries;
 
 
 	CLodHandler();
 	CLodHandler();
 	~CLodHandler();
 	~CLodHandler();