浏览代码

Merge pull request #1020 from eightyeight/simdictionary-improvement

SimDictionary improvement
Daniel Buckmaster 10 年之前
父节点
当前提交
c85ac03c16

+ 73 - 19
Engine/source/console/simDictionary.cpp

@@ -29,19 +29,23 @@ extern U32 HashPointer(StringTableEntry e);
 
 SimNameDictionary::SimNameDictionary()
 {
+#ifndef USE_NEW_SIMDICTIONARY
    hashTable = NULL;
+#endif
    mutex = Mutex::createMutex();
 }
 
 SimNameDictionary::~SimNameDictionary()
 {
+#ifndef USE_NEW_SIMDICTIONARY
    delete[] hashTable;
+#endif
    Mutex::destroyMutex(mutex);
 }
 
 void SimNameDictionary::insert(SimObject* obj)
 {
-   if(!obj->objectName)
+   if(!obj || !obj->objectName)
       return;
 
    SimObject* checkForDup = find(obj->objectName);
@@ -50,7 +54,7 @@ void SimNameDictionary::insert(SimObject* obj)
       Con::warnf("Warning! You have a duplicate datablock name of %s. This can cause problems. You should rename one of them.", obj->objectName);
 
    Mutex::lockMutex(mutex);
-   
+#ifndef USE_NEW_SIMDICTIONARY
    if(!hashTable)
    {
       hashTable = new SimObject *[DefaultTableSize];
@@ -95,12 +99,15 @@ void SimNameDictionary::insert(SimObject* obj)
       hashTable = newHashTable;
       hashTableSize = newHashTableSize;
    }
-   
+#else
+   root[obj->objectName] = obj;
+#endif
    Mutex::unlockMutex(mutex);
 }
 
 SimObject* SimNameDictionary::find(StringTableEntry name)
 {
+#ifndef USE_NEW_SIMDICTIONARY
    // NULL is a valid lookup - it will always return NULL
    if(!hashTable)
       return NULL;
@@ -121,15 +128,22 @@ SimObject* SimNameDictionary::find(StringTableEntry name)
 
    Mutex::unlockMutex(mutex);
    return NULL;
+#else
+  Mutex::lockMutex(mutex);
+  StringDictDef::iterator it = root.find(name);
+  SimObject* f = (it == root.end() ? NULL : it->second);
+  Mutex::unlockMutex(mutex);
+  return f;
+#endif
 }
 
 void SimNameDictionary::remove(SimObject* obj)
 {
-   if(!obj->objectName)
+   if(!obj || !obj->objectName)
       return;
 
    Mutex::lockMutex(mutex);
-
+#ifndef USE_NEW_SIMDICTIONARY
    SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize];
    while(*walk)
    {
@@ -144,7 +158,11 @@ void SimNameDictionary::remove(SimObject* obj)
       }
       walk = &((*walk)->nextNameObject);
    }
-
+#else
+   const char* name = obj->objectName;
+   if (root.find(name) != root.end())
+      root.erase(name);
+#endif
    Mutex::unlockMutex(mutex);
 }	
 
@@ -152,28 +170,31 @@ void SimNameDictionary::remove(SimObject* obj)
 
 SimManagerNameDictionary::SimManagerNameDictionary()
 {
+#ifndef USE_NEW_SIMDICTIONARY
    hashTable = new SimObject *[DefaultTableSize];
    hashTableSize = DefaultTableSize;
    hashEntryCount = 0;
    
    dMemset( hashTable, 0, sizeof( hashTable[ 0 ] ) * hashTableSize );
-
+#endif
    mutex = Mutex::createMutex();
 }
 
 SimManagerNameDictionary::~SimManagerNameDictionary()
 {
+#ifndef USE_NEW_SIMDICTIONARY
    delete[] hashTable;
+#endif
    Mutex::destroyMutex(mutex);
 }
 
 void SimManagerNameDictionary::insert(SimObject* obj)
 {
-   if(!obj->objectName)
+   if(!obj || !obj->objectName)
       return;
 
    Mutex::lockMutex(mutex);
-
+#ifndef USE_NEW_SIMDICTIONARY
    S32 idx = HashPointer(obj->objectName) % hashTableSize;
    obj->nextManagerNameObject = hashTable[idx];
    hashTable[idx] = obj;
@@ -209,7 +230,9 @@ void SimManagerNameDictionary::insert(SimObject* obj)
       hashTable = newHashTable;
       hashTableSize = newHashTableSize;
    }
-   
+#else
+   root[obj->objectName] = obj;
+#endif
    Mutex::unlockMutex(mutex);
 }
 
@@ -219,6 +242,7 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name)
 
    Mutex::lockMutex(mutex);
 
+#ifndef USE_NEW_SIMDICTIONARY
    S32 idx = HashPointer(name) % hashTableSize;
    SimObject *walk = hashTable[idx];
    while(walk)
@@ -230,16 +254,23 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name)
       }
       walk = walk->nextManagerNameObject;
    }
-
    Mutex::unlockMutex(mutex);
+
    return NULL;
+#else
+   StringDictDef::iterator it = root.find(name);
+   SimObject* f = (it == root.end() ? NULL : it->second);
+   Mutex::unlockMutex(mutex);
+   return f;
+#endif
 }
 
 void SimManagerNameDictionary::remove(SimObject* obj)
 {
-   if(!obj->objectName)
+   if(!obj || !obj->objectName)
       return;
 
+#ifndef USE_NEW_SIMDICTIONARY
    Mutex::lockMutex(mutex);
 
    SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize];
@@ -256,7 +287,11 @@ void SimManagerNameDictionary::remove(SimObject* obj)
       }
       walk = &((*walk)->nextManagerNameObject);
    }
-
+#else
+   StringTableEntry name = obj->objectName;
+   if (root.find(name) != root.end())
+      root.erase(name);
+#endif
    Mutex::unlockMutex(mutex);
 }	
 
@@ -265,7 +300,9 @@ void SimManagerNameDictionary::remove(SimObject* obj)
 
 SimIdDictionary::SimIdDictionary()
 {
+#ifndef USE_NEW_SIMDICTIONARY
    dMemset( table, 0, sizeof( table[ 0 ] ) * DefaultTableSize );
+#endif
    mutex = Mutex::createMutex();
 }
 
@@ -274,22 +311,29 @@ SimIdDictionary::~SimIdDictionary()
    Mutex::destroyMutex(mutex);
 }
 
+
+
 void SimIdDictionary::insert(SimObject* obj)
 {
-   Mutex::lockMutex(mutex);
+   if (!obj)
+      return;
 
+   Mutex::lockMutex(mutex);
+#ifndef USE_NEW_SIMDICTIONARY
    S32 idx = obj->getId() & TableBitMask;
    obj->nextIdObject = table[idx];
    AssertFatal( obj->nextIdObject != obj, "SimIdDictionary::insert - Creating Infinite Loop linking to self!" );
    table[idx] = obj;
-
+#else
+   root[obj->getId()] = obj;
+#endif
    Mutex::unlockMutex(mutex);
 }
 
 SimObject* SimIdDictionary::find(S32 id)
 {
    Mutex::lockMutex(mutex);
-
+#ifndef USE_NEW_SIMDICTIONARY
    S32 idx = id & TableBitMask;
    SimObject *walk = table[idx];
    while(walk)
@@ -301,22 +345,32 @@ SimObject* SimIdDictionary::find(S32 id)
       }
       walk = walk->nextIdObject;
    }
-
    Mutex::unlockMutex(mutex);
 
    return NULL;
+#else
+   SimObjectIdDictDef::iterator it = root.find(id);
+   SimObject* f = (it == root.end() ? NULL : it->second);
+   Mutex::unlockMutex(mutex);
+   return f;
+#endif
 }
 
 void SimIdDictionary::remove(SimObject* obj)
 {
-   Mutex::lockMutex(mutex);
+   if (!obj)
+      return;
 
+   Mutex::lockMutex(mutex);
+#ifndef USE_NEW_SIMDICTIONARY
    SimObject **walk = &table[obj->getId() & TableBitMask];
    while(*walk && *walk != obj)
       walk = &((*walk)->nextIdObject);
    if(*walk)
       *walk = obj->nextIdObject;
-
+#else
+   root.erase(obj->getId());
+#endif
    Mutex::unlockMutex(mutex);
 }
 

+ 42 - 0
Engine/source/console/simDictionary.h

@@ -33,8 +33,38 @@
 #include "platform/threads/mutex.h"
 #endif
 
+#include "torqueConfig.h"
+
 class SimObject;
 
+#ifdef USE_NEW_SIMDICTIONARY
+#include <string>
+#include <unordered_map>
+
+#ifndef _SIM_H_
+#include "console/sim.h"
+#endif
+
+struct StringTableEntryHash
+{
+   inline size_t operator()(StringTableEntry val) const
+   {
+      return (size_t)val;
+   }
+};
+
+struct StringTableEntryEq
+{
+   inline bool operator()(StringTableEntry s1, StringTableEntry s2) const
+   {
+      return s1 == s2;
+   }
+};
+
+typedef std::unordered_map<StringTableEntry, SimObject*, StringTableEntryHash, StringTableEntryEq> StringDictDef;	
+typedef std::unordered_map<SimObjectId, SimObject*> SimObjectIdDictDef;
+#endif
+
 //----------------------------------------------------------------------------
 /// Map of names to SimObjects
 ///
@@ -42,6 +72,7 @@ class SimObject;
 /// for fast removal of an object given object*
 class SimNameDictionary
 {
+#ifndef USE_NEW_SIMDICTIONARY
    enum
    {
       DefaultTableSize = 29
@@ -50,6 +81,9 @@ class SimNameDictionary
    SimObject **hashTable;  // hash the pointers of the names...
    S32 hashTableSize;
    S32 hashEntryCount;
+#else
+   StringDictDef root;
+#endif
 
    void *mutex;
 
@@ -64,6 +98,7 @@ public:
 
 class SimManagerNameDictionary
 {
+#ifndef USE_NEW_SIMDICTIONARY
    enum
    {
       DefaultTableSize = 29
@@ -72,6 +107,9 @@ class SimManagerNameDictionary
    SimObject **hashTable;  // hash the pointers of the names...
    S32 hashTableSize;
    S32 hashEntryCount;
+#else
+   StringDictDef root;
+#endif
 
    void *mutex;
 
@@ -91,12 +129,16 @@ public:
 /// for fast removal of an object given object*
 class SimIdDictionary
 {
+#ifndef USE_NEW_SIMDICTIONARY
    enum
    {
       DefaultTableSize = 4096,
       TableBitMask = 4095
    };
    SimObject *table[DefaultTableSize];
+#else
+   SimObjectIdDictDef root;
+#endif
 
    void *mutex;
 

+ 5 - 0
Templates/Empty/source/torqueConfig.h

@@ -52,6 +52,11 @@
 #define TORQUE_DISABLE_MEMORY_MANAGER
 #endif
 
+/// The improved SimDictionary uses C++11 and is designed for games where
+/// there are over 10000 simobjects active normally. To enable the new
+/// SimDictionary just uncomment the line below.
+//#define USE_NEW_SIMDICTIONARY
+
 /// Define me if you want to disable the virtual mount system.
 //#define TORQUE_DISABLE_VIRTUAL_MOUNT_SYSTEM
 

+ 5 - 0
Templates/Full/source/torqueConfig.h

@@ -52,6 +52,11 @@
 #define TORQUE_DISABLE_MEMORY_MANAGER
 #endif
 
+/// The improved SimDictionary uses C++11 and is designed for games where
+/// there are over 10000 simobjects active normally. To enable the new
+/// SimDictionary just uncomment the line below.
+//#define USE_NEW_SIMDICTIONARY
+
 /// Define me if you want to disable the virtual mount system.
 //#define TORQUE_DISABLE_VIRTUAL_MOUNT_SYSTEM