From a91e5a2590f437e1f2630db657e02376546df6bc Mon Sep 17 00:00:00 2001 From: Vincent Gee Date: Tue, 4 Nov 2014 06:30:35 -0500 Subject: [PATCH 1/7] Improvements to SimDictionary for when you have a large number of objects in the game. Under light load (i.e. under 5000 objects) this code actually runs slower that the stock simdictionary. When you exceed 5000 objects, the template class actually runs faster and more consistently. --- Engine/source/console/simDictionary.cpp | 75 ++++++++++++++++++++----- Engine/source/console/simDictionary.h | 50 ++++++++++++++++- Templates/Empty/source/torqueConfig.h | 4 ++ Templates/Full/source/torqueConfig.h | 4 ++ 4 files changed, 116 insertions(+), 17 deletions(-) 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" From d3aaabc976c3bd43e06d9931d5ee0bc4374b7489 Mon Sep 17 00:00:00 2001 From: Vincent Gee Date: Tue, 4 Nov 2014 20:05:39 -0500 Subject: [PATCH 2/7] Made fixes --- Engine/source/console/simDictionary.h | 41 ++++++++++++++++----------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/Engine/source/console/simDictionary.h b/Engine/source/console/simDictionary.h index 5dddf4bbe..120791b06 100644 --- a/Engine/source/console/simDictionary.h +++ b/Engine/source/console/simDictionary.h @@ -33,32 +33,39 @@ #include "platform/threads/mutex.h" #endif +#ifndef USE_CLASSIC_SIMDICTIONARY #include #include #include "TorqueConfig.h" - +#endif 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; + +#include "core/strings/stringFunctions.h" + +struct DictionaryHash +{ + 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; + } +}; +#endif + +#ifndef USE_CLASSIC_SIMDICTIONARY +typedef std::unordered_map StringDictDef; typedef std::unordered_map U32DictDef; #endif From f0a16bb9e3ce457bf1118f932847b09e43937cfe Mon Sep 17 00:00:00 2001 From: Vincent Gee Date: Wed, 5 Nov 2014 16:47:07 -0500 Subject: [PATCH 3/7] More comments added, move #include --- Engine/source/console/simDictionary.h | 4 ++-- Templates/Empty/source/torqueConfig.h | 3 +++ Templates/Full/source/torqueConfig.h | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Engine/source/console/simDictionary.h b/Engine/source/console/simDictionary.h index 120791b06..ab6662013 100644 --- a/Engine/source/console/simDictionary.h +++ b/Engine/source/console/simDictionary.h @@ -33,11 +33,11 @@ #include "platform/threads/mutex.h" #endif +#include "TorqueConfig.h" + #ifndef USE_CLASSIC_SIMDICTIONARY #include #include - -#include "TorqueConfig.h" #endif class SimObject; diff --git a/Templates/Empty/source/torqueConfig.h b/Templates/Empty/source/torqueConfig.h index 7e433f67b..116111ff5 100644 --- a/Templates/Empty/source/torqueConfig.h +++ b/Templates/Empty/source/torqueConfig.h @@ -34,6 +34,9 @@ //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. +//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 comment out the line below. #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 777e39a37..336d53f8c 100644 --- a/Templates/Full/source/torqueConfig.h +++ b/Templates/Full/source/torqueConfig.h @@ -34,6 +34,9 @@ //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. +//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 comment out the line below. #define USE_CLASSIC_SIMDICTIONARY /// What's the name of your application? Used in a variety of places. #define TORQUE_APP_NAME "Full" From 26c5451593233f19f7c8d432122596932ebd8bda Mon Sep 17 00:00:00 2001 From: Vincent Gee Date: Wed, 5 Nov 2014 17:41:31 -0500 Subject: [PATCH 4/7] fixed capital T --- Engine/source/console/simDictionary.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/source/console/simDictionary.h b/Engine/source/console/simDictionary.h index ab6662013..bd10d9300 100644 --- a/Engine/source/console/simDictionary.h +++ b/Engine/source/console/simDictionary.h @@ -33,7 +33,7 @@ #include "platform/threads/mutex.h" #endif -#include "TorqueConfig.h" +#include "torqueConfig.h" #ifndef USE_CLASSIC_SIMDICTIONARY #include From 116276a105b0ac34ee1c984b901345a482a8aeb5 Mon Sep 17 00:00:00 2001 From: Daniel Buckmaster Date: Mon, 8 Dec 2014 10:20:38 +1100 Subject: [PATCH 5/7] Tweaks so I'm happy with it. * Change #define usage * Fix tabs --- Engine/source/console/simDictionary.cpp | 39 ++++++++-------- Engine/source/console/simDictionary.h | 59 +++++++++++-------------- Templates/Empty/source/torqueConfig.h | 12 +++-- Templates/Full/source/torqueConfig.h | 12 +++-- 4 files changed, 54 insertions(+), 68 deletions(-) diff --git a/Engine/source/console/simDictionary.cpp b/Engine/source/console/simDictionary.cpp index 3e25828da..5196d994b 100644 --- a/Engine/source/console/simDictionary.cpp +++ b/Engine/source/console/simDictionary.cpp @@ -30,7 +30,7 @@ extern U32 HashPointer(StringTableEntry e); SimNameDictionary::SimNameDictionary() { -#ifdef USE_CLASSIC_SIMDICTIONARY +#ifndef USE_NEW_SIMDICTIONARY hashTable = NULL; #endif mutex = Mutex::createMutex(); @@ -38,7 +38,7 @@ SimNameDictionary::SimNameDictionary() SimNameDictionary::~SimNameDictionary() { -#ifdef USE_CLASSIC_SIMDICTIONARY +#ifndef USE_NEW_SIMDICTIONARY delete[] hashTable; #endif Mutex::destroyMutex(mutex); @@ -55,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 +#ifndef USE_NEW_SIMDICTIONARY if(!hashTable) { hashTable = new SimObject *[DefaultTableSize]; @@ -108,7 +108,7 @@ void SimNameDictionary::insert(SimObject* obj) SimObject* SimNameDictionary::find(StringTableEntry name) { -#ifdef USE_CLASSIC_SIMDICTIONARY +#ifndef USE_NEW_SIMDICTIONARY // NULL is a valid lookup - it will always return NULL if(!hashTable) return NULL; @@ -143,7 +143,7 @@ void SimNameDictionary::remove(SimObject* obj) return; Mutex::lockMutex(mutex); -#ifdef USE_CLASSIC_SIMDICTIONARY +#ifndef USE_NEW_SIMDICTIONARY SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize]; while(*walk) { @@ -161,7 +161,7 @@ void SimNameDictionary::remove(SimObject* obj) #else const char* name = StringTable->insert(obj->objectName); if (root[name]) - root.erase(name); + root.erase(name); #endif Mutex::unlockMutex(mutex); } @@ -170,7 +170,7 @@ void SimNameDictionary::remove(SimObject* obj) SimManagerNameDictionary::SimManagerNameDictionary() { -#ifdef USE_CLASSIC_SIMDICTIONARY +#ifndef USE_NEW_SIMDICTIONARY hashTable = new SimObject *[DefaultTableSize]; hashTableSize = DefaultTableSize; hashEntryCount = 0; @@ -182,7 +182,7 @@ SimManagerNameDictionary::SimManagerNameDictionary() SimManagerNameDictionary::~SimManagerNameDictionary() { -#ifdef USE_CLASSIC_SIMDICTIONARY +#ifndef USE_NEW_SIMDICTIONARY delete[] hashTable; #endif Mutex::destroyMutex(mutex); @@ -194,7 +194,7 @@ void SimManagerNameDictionary::insert(SimObject* obj) return; Mutex::lockMutex(mutex); -#ifdef USE_CLASSIC_SIMDICTIONARY +#ifndef USE_NEW_SIMDICTIONARY S32 idx = HashPointer(obj->objectName) % hashTableSize; obj->nextManagerNameObject = hashTable[idx]; hashTable[idx] = obj; @@ -242,7 +242,7 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name) Mutex::lockMutex(mutex); -#ifdef USE_CLASSIC_SIMDICTIONARY +#ifndef USE_NEW_SIMDICTIONARY S32 idx = HashPointer(name) % hashTableSize; SimObject *walk = hashTable[idx]; while(walk) @@ -258,7 +258,7 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name) return NULL; #else - SimObject* f = root[StringTable->insert(name)]; + SimObject* f = root[StringTable->insert(name)]; Mutex::unlockMutex(mutex); return f; #endif @@ -269,7 +269,7 @@ void SimManagerNameDictionary::remove(SimObject* obj) if(!obj->objectName) return; -#ifdef USE_CLASSIC_SIMDICTIONARY +#ifndef USE_NEW_SIMDICTIONARY Mutex::lockMutex(mutex); SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize]; @@ -287,10 +287,9 @@ void SimManagerNameDictionary::remove(SimObject* obj) walk = &((*walk)->nextManagerNameObject); } #else - - const char* name = StringTable->insert(obj->objectName); - if (root[name]) - root.erase(name); + const char* name = StringTable->insert(obj->objectName); + if (root[name]) + root.erase(name); #endif Mutex::unlockMutex(mutex); } @@ -300,7 +299,7 @@ void SimManagerNameDictionary::remove(SimObject* obj) SimIdDictionary::SimIdDictionary() { -#ifdef USE_CLASSIC_SIMDICTIONARY +#ifndef USE_NEW_SIMDICTIONARY dMemset( table, 0, sizeof( table[ 0 ] ) * DefaultTableSize ); #endif mutex = Mutex::createMutex(); @@ -316,7 +315,7 @@ SimIdDictionary::~SimIdDictionary() void SimIdDictionary::insert(SimObject* obj) { Mutex::lockMutex(mutex); -#ifdef USE_CLASSIC_SIMDICTIONARY +#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!" ); @@ -330,7 +329,7 @@ void SimIdDictionary::insert(SimObject* obj) SimObject* SimIdDictionary::find(S32 id) { Mutex::lockMutex(mutex); -#ifdef USE_CLASSIC_SIMDICTIONARY +#ifndef USE_NEW_SIMDICTIONARY S32 idx = id & TableBitMask; SimObject *walk = table[idx]; while(walk) @@ -355,7 +354,7 @@ SimObject* SimIdDictionary::find(S32 id) void SimIdDictionary::remove(SimObject* obj) { Mutex::lockMutex(mutex); -#ifdef USE_CLASSIC_SIMDICTIONARY +#ifndef USE_NEW_SIMDICTIONARY SimObject **walk = &table[obj->getId() & TableBitMask]; while(*walk && *walk != obj) walk = &((*walk)->nextIdObject); diff --git a/Engine/source/console/simDictionary.h b/Engine/source/console/simDictionary.h index bd10d9300..27d27de29 100644 --- a/Engine/source/console/simDictionary.h +++ b/Engine/source/console/simDictionary.h @@ -35,38 +35,32 @@ #include "torqueConfig.h" -#ifndef USE_CLASSIC_SIMDICTIONARY -#include -#include -#endif - class SimObject; - -#ifndef USE_CLASSIC_SIMDICTIONARY +#ifdef USE_NEW_SIMDICTIONARY +#include +#include #include "core/strings/stringFunctions.h" -struct DictionaryHash +struct DictionaryHash { - inline size_t operator()(const char* val) const - { - return (long)val; - } + 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; - } -}; -#endif -#ifndef USE_CLASSIC_SIMDICTIONARY -typedef std::unordered_map StringDictDef; -typedef std::unordered_map U32DictDef; +struct eqstr +{ + inline bool operator()(const char *s1, const char *s2) const + { + return dStrcmp(s1, s2) == 0; + } +}; + +typedef std::unordered_map StringDictDef; +typedef std::unordered_map U32DictDef; #endif @@ -78,7 +72,7 @@ typedef std::unordered_map U32DictDef; /// for fast removal of an object given object* class SimNameDictionary { -#ifdef USE_CLASSIC_SIMDICTIONARY +#ifndef USE_NEW_SIMDICTIONARY enum { DefaultTableSize = 29 @@ -90,10 +84,9 @@ class SimNameDictionary #else StringDictDef root; #endif + void *mutex; - - public: void insert(SimObject* obj); void remove(SimObject* obj); @@ -105,7 +98,7 @@ public: class SimManagerNameDictionary { -#ifdef USE_CLASSIC_SIMDICTIONARY +#ifndef USE_NEW_SIMDICTIONARY enum { DefaultTableSize = 29 @@ -114,15 +107,12 @@ class SimManagerNameDictionary 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); @@ -139,7 +129,7 @@ public: /// for fast removal of an object given object* class SimIdDictionary { -#ifdef USE_CLASSIC_SIMDICTIONARY +#ifndef USE_NEW_SIMDICTIONARY enum { DefaultTableSize = 4096, @@ -149,6 +139,7 @@ class SimIdDictionary #else U32DictDef root; #endif + void *mutex; public: diff --git a/Templates/Empty/source/torqueConfig.h b/Templates/Empty/source/torqueConfig.h index 116111ff5..23d7f9ca3 100644 --- a/Templates/Empty/source/torqueConfig.h +++ b/Templates/Empty/source/torqueConfig.h @@ -31,13 +31,6 @@ //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. - -//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 comment out the line below. -#define USE_CLASSIC_SIMDICTIONARY /// What's the name of your application? Used in a variety of places. #define TORQUE_APP_NAME "Empty" @@ -59,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 diff --git a/Templates/Full/source/torqueConfig.h b/Templates/Full/source/torqueConfig.h index 336d53f8c..56fa42bec 100644 --- a/Templates/Full/source/torqueConfig.h +++ b/Templates/Full/source/torqueConfig.h @@ -31,13 +31,6 @@ //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. - -//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 comment out the line below. -#define USE_CLASSIC_SIMDICTIONARY /// What's the name of your application? Used in a variety of places. #define TORQUE_APP_NAME "Full" @@ -59,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 From 7004ec627e9e99075e247c7ffbb6a37fc5f4eab9 Mon Sep 17 00:00:00 2001 From: Daniel Buckmaster Date: Wed, 10 Dec 2014 14:04:26 +1100 Subject: [PATCH 6/7] Use find instead of [] and call StringTable->insert less. --- Engine/source/console/simDictionary.cpp | 21 ++++++++++++--------- Engine/source/console/simDictionary.h | 22 +++++++++++++--------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/Engine/source/console/simDictionary.cpp b/Engine/source/console/simDictionary.cpp index 5196d994b..c1b0bf056 100644 --- a/Engine/source/console/simDictionary.cpp +++ b/Engine/source/console/simDictionary.cpp @@ -101,7 +101,7 @@ void SimNameDictionary::insert(SimObject* obj) hashTableSize = newHashTableSize; } #else - root[StringTable->insert(obj->objectName)] = obj; + root[obj->objectName] = obj; #endif Mutex::unlockMutex(mutex); } @@ -131,7 +131,8 @@ SimObject* SimNameDictionary::find(StringTableEntry name) return NULL; #else Mutex::lockMutex(mutex); - SimObject* f = root[StringTable->insert(name)]; + StringDictDef::iterator it = root.find(name); + SimObject* f = (it == root.end() ? NULL : it->second); Mutex::unlockMutex(mutex); return f; #endif @@ -159,8 +160,8 @@ void SimNameDictionary::remove(SimObject* obj) walk = &((*walk)->nextNameObject); } #else - const char* name = StringTable->insert(obj->objectName); - if (root[name]) + const char* name = obj->objectName; + if (root.find(name) != root.end()) root.erase(name); #endif Mutex::unlockMutex(mutex); @@ -231,7 +232,7 @@ void SimManagerNameDictionary::insert(SimObject* obj) hashTableSize = newHashTableSize; } #else - root[StringTable->insert(obj->objectName)] = obj; + root[obj->objectName] = obj; #endif Mutex::unlockMutex(mutex); } @@ -258,7 +259,8 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name) return NULL; #else - SimObject* f = root[StringTable->insert(name)]; + StringDictDef::iterator it = root.find(name); + SimObject* f = (it == root.end() ? NULL : it->second); Mutex::unlockMutex(mutex); return f; #endif @@ -287,8 +289,8 @@ void SimManagerNameDictionary::remove(SimObject* obj) walk = &((*walk)->nextManagerNameObject); } #else - const char* name = StringTable->insert(obj->objectName); - if (root[name]) + StringTableEntry name = obj->objectName; + if (root.find(name) != root.end()) root.erase(name); #endif Mutex::unlockMutex(mutex); @@ -345,7 +347,8 @@ SimObject* SimIdDictionary::find(S32 id) return NULL; #else - SimObject* f = root[id]; + SimObjectIdDictDef::iterator it = root.find(id); + SimObject* f = (it == root.end() ? NULL : it->second); Mutex::unlockMutex(mutex); return f; #endif diff --git a/Engine/source/console/simDictionary.h b/Engine/source/console/simDictionary.h index 27d27de29..f32c8b8d0 100644 --- a/Engine/source/console/simDictionary.h +++ b/Engine/source/console/simDictionary.h @@ -41,26 +41,30 @@ class SimObject; #include #include +#ifndef _SIM_H_ +#include "console/sim.h" +#endif + #include "core/strings/stringFunctions.h" -struct DictionaryHash +struct StringTableEntryHash { - inline size_t operator()(const char* val) const + inline size_t operator()(StringTableEntry val) const { - return (long)val; + return (size_t)val; } }; -struct eqstr +struct StringTableEntryEq { - inline bool operator()(const char *s1, const char *s2) const + inline bool operator()(StringTableEntry s1, StringTableEntry s2) const { - return dStrcmp(s1, s2) == 0; + return s1 == s2; } }; -typedef std::unordered_map StringDictDef; -typedef std::unordered_map U32DictDef; +typedef std::unordered_map StringDictDef; +typedef std::unordered_map SimObjectIdDictDef; #endif @@ -137,7 +141,7 @@ class SimIdDictionary }; SimObject *table[DefaultTableSize]; #else - U32DictDef root; + SimObjectIdDictDef root; #endif void *mutex; From 859514a7927af9d4e86b9945561cd9ecbd5d9678 Mon Sep 17 00:00:00 2001 From: Daniel Buckmaster Date: Tue, 23 Dec 2014 22:17:00 +1100 Subject: [PATCH 7/7] Guard against null pointers and remove unnecessary include. --- Engine/source/console/simDictionary.cpp | 15 ++++++++++----- Engine/source/console/simDictionary.h | 4 ---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Engine/source/console/simDictionary.cpp b/Engine/source/console/simDictionary.cpp index c1b0bf056..03fadb990 100644 --- a/Engine/source/console/simDictionary.cpp +++ b/Engine/source/console/simDictionary.cpp @@ -23,7 +23,6 @@ #include "console/simDictionary.h" #include "console/simBase.h" - //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- extern U32 HashPointer(StringTableEntry e); @@ -46,7 +45,7 @@ SimNameDictionary::~SimNameDictionary() void SimNameDictionary::insert(SimObject* obj) { - if(!obj->objectName) + if(!obj || !obj->objectName) return; SimObject* checkForDup = find(obj->objectName); @@ -140,7 +139,7 @@ SimObject* SimNameDictionary::find(StringTableEntry name) void SimNameDictionary::remove(SimObject* obj) { - if(!obj->objectName) + if(!obj || !obj->objectName) return; Mutex::lockMutex(mutex); @@ -191,7 +190,7 @@ SimManagerNameDictionary::~SimManagerNameDictionary() void SimManagerNameDictionary::insert(SimObject* obj) { - if(!obj->objectName) + if(!obj || !obj->objectName) return; Mutex::lockMutex(mutex); @@ -268,7 +267,7 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name) void SimManagerNameDictionary::remove(SimObject* obj) { - if(!obj->objectName) + if(!obj || !obj->objectName) return; #ifndef USE_NEW_SIMDICTIONARY @@ -316,6 +315,9 @@ SimIdDictionary::~SimIdDictionary() void SimIdDictionary::insert(SimObject* obj) { + if (!obj) + return; + Mutex::lockMutex(mutex); #ifndef USE_NEW_SIMDICTIONARY S32 idx = obj->getId() & TableBitMask; @@ -356,6 +358,9 @@ SimObject* SimIdDictionary::find(S32 id) void SimIdDictionary::remove(SimObject* obj) { + if (!obj) + return; + Mutex::lockMutex(mutex); #ifndef USE_NEW_SIMDICTIONARY SimObject **walk = &table[obj->getId() & TableBitMask]; diff --git a/Engine/source/console/simDictionary.h b/Engine/source/console/simDictionary.h index f32c8b8d0..bbfb0f385 100644 --- a/Engine/source/console/simDictionary.h +++ b/Engine/source/console/simDictionary.h @@ -45,8 +45,6 @@ class SimObject; #include "console/sim.h" #endif -#include "core/strings/stringFunctions.h" - struct StringTableEntryHash { inline size_t operator()(StringTableEntry val) const @@ -67,8 +65,6 @@ typedef std::unordered_map SimObjectIdDictDef; #endif - - //---------------------------------------------------------------------------- /// Map of names to SimObjects ///