diff --git a/Engine/source/console/simDictionary.cpp b/Engine/source/console/simDictionary.cpp index dac603517..3e25828da 100644 --- a/Engine/source/console/simDictionary.cpp +++ b/Engine/source/console/simDictionary.cpp @@ -23,19 +23,24 @@ #include "console/simDictionary.h" #include "console/simBase.h" + //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- extern U32 HashPointer(StringTableEntry e); SimNameDictionary::SimNameDictionary() { +#ifdef USE_CLASSIC_SIMDICTIONARY hashTable = NULL; +#endif mutex = Mutex::createMutex(); } SimNameDictionary::~SimNameDictionary() { +#ifdef USE_CLASSIC_SIMDICTIONARY delete[] hashTable; +#endif Mutex::destroyMutex(mutex); } @@ -50,7 +55,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); - +#ifdef USE_CLASSIC_SIMDICTIONARY if(!hashTable) { hashTable = new SimObject *[DefaultTableSize]; @@ -95,12 +100,15 @@ void SimNameDictionary::insert(SimObject* obj) hashTable = newHashTable; hashTableSize = newHashTableSize; } - +#else + root[StringTable->insert(obj->objectName)] = obj; +#endif Mutex::unlockMutex(mutex); } SimObject* SimNameDictionary::find(StringTableEntry name) { +#ifdef USE_CLASSIC_SIMDICTIONARY // NULL is a valid lookup - it will always return NULL if(!hashTable) return NULL; @@ -121,6 +129,12 @@ SimObject* SimNameDictionary::find(StringTableEntry name) Mutex::unlockMutex(mutex); return NULL; +#else + Mutex::lockMutex(mutex); + SimObject* f = root[StringTable->insert(name)]; + Mutex::unlockMutex(mutex); + return f; +#endif } void SimNameDictionary::remove(SimObject* obj) @@ -129,7 +143,7 @@ void SimNameDictionary::remove(SimObject* obj) return; Mutex::lockMutex(mutex); - +#ifdef USE_CLASSIC_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 = StringTable->insert(obj->objectName); + if (root[name]) + root.erase(name); +#endif Mutex::unlockMutex(mutex); } @@ -152,18 +170,21 @@ void SimNameDictionary::remove(SimObject* obj) SimManagerNameDictionary::SimManagerNameDictionary() { +#ifdef USE_CLASSIC_SIMDICTIONARY hashTable = new SimObject *[DefaultTableSize]; hashTableSize = DefaultTableSize; hashEntryCount = 0; dMemset( hashTable, 0, sizeof( hashTable[ 0 ] ) * hashTableSize ); - +#endif mutex = Mutex::createMutex(); } SimManagerNameDictionary::~SimManagerNameDictionary() { +#ifdef USE_CLASSIC_SIMDICTIONARY delete[] hashTable; +#endif Mutex::destroyMutex(mutex); } @@ -173,7 +194,7 @@ void SimManagerNameDictionary::insert(SimObject* obj) return; Mutex::lockMutex(mutex); - +#ifdef USE_CLASSIC_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[StringTable->insert(obj->objectName)] = obj; +#endif Mutex::unlockMutex(mutex); } @@ -219,6 +242,7 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name) Mutex::lockMutex(mutex); +#ifdef USE_CLASSIC_SIMDICTIONARY S32 idx = HashPointer(name) % hashTableSize; SimObject *walk = hashTable[idx]; while(walk) @@ -230,9 +254,14 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name) } walk = walk->nextManagerNameObject; } - Mutex::unlockMutex(mutex); + return NULL; +#else + SimObject* f = root[StringTable->insert(name)]; + Mutex::unlockMutex(mutex); + return f; +#endif } void SimManagerNameDictionary::remove(SimObject* obj) @@ -240,6 +269,7 @@ void SimManagerNameDictionary::remove(SimObject* obj) if(!obj->objectName) return; +#ifdef USE_CLASSIC_SIMDICTIONARY Mutex::lockMutex(mutex); SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize]; @@ -256,7 +286,12 @@ void SimManagerNameDictionary::remove(SimObject* obj) } walk = &((*walk)->nextManagerNameObject); } +#else + const char* name = StringTable->insert(obj->objectName); + if (root[name]) + root.erase(name); +#endif Mutex::unlockMutex(mutex); } @@ -265,7 +300,9 @@ void SimManagerNameDictionary::remove(SimObject* obj) SimIdDictionary::SimIdDictionary() { +#ifdef USE_CLASSIC_SIMDICTIONARY dMemset( table, 0, sizeof( table[ 0 ] ) * DefaultTableSize ); +#endif mutex = Mutex::createMutex(); } @@ -274,22 +311,26 @@ SimIdDictionary::~SimIdDictionary() Mutex::destroyMutex(mutex); } + + void SimIdDictionary::insert(SimObject* obj) { Mutex::lockMutex(mutex); - +#ifdef USE_CLASSIC_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); - +#ifdef USE_CLASSIC_SIMDICTIONARY S32 idx = id & TableBitMask; SimObject *walk = table[idx]; while(walk) @@ -301,22 +342,28 @@ SimObject* SimIdDictionary::find(S32 id) } walk = walk->nextIdObject; } - Mutex::unlockMutex(mutex); return NULL; +#else + SimObject* f = root[id]; + Mutex::unlockMutex(mutex); + return f; +#endif } void SimIdDictionary::remove(SimObject* obj) { Mutex::lockMutex(mutex); - +#ifdef USE_CLASSIC_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); } diff --git a/Engine/source/console/simDictionary.h b/Engine/source/console/simDictionary.h index 75fc075e2..5dddf4bbe 100644 --- a/Engine/source/console/simDictionary.h +++ b/Engine/source/console/simDictionary.h @@ -33,8 +33,37 @@ #include "platform/threads/mutex.h" #endif +#include +#include + +#include "TorqueConfig.h" + + class SimObject; +#include "core/strings/stringFunctions.h" + +struct my_hash { + inline size_t operator()(const char* val) const + { + return (long)val; + } + }; + + struct eqstr { + inline bool operator()(const char *s1, const char *s2) const { + return dStrcmp(s1, s2) == 0; + } + }; + + +#ifndef USE_CLASSIC_SIMDICTIONARY +typedef std::unordered_map StringDictDef; +typedef std::unordered_map U32DictDef; +#endif + + + //---------------------------------------------------------------------------- /// Map of names to SimObjects /// @@ -42,6 +71,7 @@ class SimObject; /// for fast removal of an object given object* class SimNameDictionary { +#ifdef USE_CLASSIC_SIMDICTIONARY enum { DefaultTableSize = 29 @@ -50,9 +80,13 @@ class SimNameDictionary SimObject **hashTable; // hash the pointers of the names... S32 hashTableSize; S32 hashEntryCount; - +#else + StringDictDef root; +#endif void *mutex; + + public: void insert(SimObject* obj); void remove(SimObject* obj); @@ -64,6 +98,7 @@ public: class SimManagerNameDictionary { +#ifdef USE_CLASSIC_SIMDICTIONARY enum { DefaultTableSize = 29 @@ -73,8 +108,14 @@ class SimManagerNameDictionary S32 hashTableSize; S32 hashEntryCount; - void *mutex; + +#else + + StringDictDef root; + +#endif + void *mutex; public: void insert(SimObject* obj); void remove(SimObject* obj); @@ -91,13 +132,16 @@ public: /// for fast removal of an object given object* class SimIdDictionary { +#ifdef USE_CLASSIC_SIMDICTIONARY enum { DefaultTableSize = 4096, TableBitMask = 4095 }; SimObject *table[DefaultTableSize]; - +#else + U32DictDef root; +#endif void *mutex; public: diff --git a/Templates/Empty/source/torqueConfig.h b/Templates/Empty/source/torqueConfig.h index d9de1b1d1..7e433f67b 100644 --- a/Templates/Empty/source/torqueConfig.h +++ b/Templates/Empty/source/torqueConfig.h @@ -31,6 +31,10 @@ //general, the information here is global for your entire codebase, applying //not only to your game proper, but also to all of your tools. +//If you plan to have less than 5000 objects use the Classic SimDictionary, if you plan to have more than +//5000 objects use the new SimDictionary. + +#define USE_CLASSIC_SIMDICTIONARY /// What's the name of your application? Used in a variety of places. #define TORQUE_APP_NAME "Empty" diff --git a/Templates/Full/source/torqueConfig.h b/Templates/Full/source/torqueConfig.h index 4d8f124f2..777e39a37 100644 --- a/Templates/Full/source/torqueConfig.h +++ b/Templates/Full/source/torqueConfig.h @@ -31,6 +31,10 @@ //general, the information here is global for your entire codebase, applying //not only to your game proper, but also to all of your tools. +//If you plan to have less than 5000 objects use the Classic SimDictionary, if you plan to have more than +//5000 objects use the new SimDictionary. + +#define USE_CLASSIC_SIMDICTIONARY /// What's the name of your application? Used in a variety of places. #define TORQUE_APP_NAME "Full"