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.

This commit is contained in:
Vincent Gee 2014-11-04 06:30:35 -05:00
parent 378a933894
commit a91e5a2590
4 changed files with 116 additions and 17 deletions

View file

@ -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);
}