Torque3D/Engine/source/console/simDictionary.cpp

380 lines
9.8 KiB
C++
Raw Normal View History

2012-09-19 15:15:01 +00:00
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "console/simDictionary.h"
#include "console/simBase.h"
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
2014-09-14 18:44:07 +00:00
extern U32 HashPointer(StringTableEntry e);
2012-09-19 15:15:01 +00:00
SimNameDictionary::SimNameDictionary()
{
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
hashTable = NULL;
#endif
2012-09-19 15:15:01 +00:00
mutex = Mutex::createMutex();
}
SimNameDictionary::~SimNameDictionary()
{
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
delete[] hashTable;
#endif
2012-09-19 15:15:01 +00:00
Mutex::destroyMutex(mutex);
}
void SimNameDictionary::insert(SimObject* obj)
{
if(!obj || !obj->objectName)
2012-09-19 15:15:01 +00:00
return;
SimObject* checkForDup = find(obj->objectName);
if (checkForDup)
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
2012-09-19 15:15:01 +00:00
if(!hashTable)
{
hashTable = new SimObject *[DefaultTableSize];
hashTableSize = DefaultTableSize;
hashEntryCount = 0;
dMemset( hashTable, 0, sizeof( *hashTable ) * DefaultTableSize );
}
S32 idx = HashPointer(obj->objectName) % hashTableSize;
obj->nextNameObject = hashTable[idx];
hashTable[idx] = obj;
hashEntryCount++;
// Rehash if necessary.
if( hashEntryCount > hashTableSize )
{
// Allocate new table.
U32 newHashTableSize = hashTableSize * 2 + 1;
SimObject** newHashTable = new SimObject *[ newHashTableSize ];
dMemset( newHashTable, 0, sizeof( newHashTable[ 0 ] ) * newHashTableSize );
// Move entries over.
for( U32 i = 0; i < hashTableSize; ++ i )
for( SimObject* object = hashTable[ i ]; object != NULL; )
{
SimObject* next = object->nextNameObject;
idx = HashPointer( object->objectName ) % newHashTableSize;
object->nextNameObject = newHashTable[ idx ];
newHashTable[ idx ] = object;
object = next;
}
// Switch tables.
delete [] hashTable;
hashTable = newHashTable;
hashTableSize = newHashTableSize;
}
#else
root[obj->objectName] = obj;
#endif
2012-09-19 15:15:01 +00:00
Mutex::unlockMutex(mutex);
}
SimObject* SimNameDictionary::find(StringTableEntry name)
{
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
// NULL is a valid lookup - it will always return NULL
if(!hashTable)
return NULL;
Mutex::lockMutex(mutex);
S32 idx = HashPointer(name) % hashTableSize;
SimObject *walk = hashTable[idx];
while(walk)
{
if(walk->objectName == name)
{
Mutex::unlockMutex(mutex);
return walk;
}
walk = walk->nextNameObject;
}
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
2012-09-19 15:15:01 +00:00
}
void SimNameDictionary::remove(SimObject* obj)
{
if(!obj || !obj->objectName)
2012-09-19 15:15:01 +00:00
return;
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize];
while(*walk)
{
if(*walk == obj)
{
*walk = obj->nextNameObject;
2017-01-12 04:34:46 +00:00
obj->nextNameObject = (SimObject*)-1;
2012-09-19 15:15:01 +00:00
hashEntryCount--;
Mutex::unlockMutex(mutex);
return;
}
walk = &((*walk)->nextNameObject);
}
#else
const char* name = obj->objectName;
if (root.find(name) != root.end())
root.erase(name);
#endif
2012-09-19 15:15:01 +00:00
Mutex::unlockMutex(mutex);
2017-01-12 04:34:46 +00:00
}
2012-09-19 15:15:01 +00:00
//----------------------------------------------------------------------------
SimManagerNameDictionary::SimManagerNameDictionary()
{
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
hashTable = new SimObject *[DefaultTableSize];
hashTableSize = DefaultTableSize;
hashEntryCount = 0;
dMemset( hashTable, 0, sizeof( hashTable[ 0 ] ) * hashTableSize );
#endif
2012-09-19 15:15:01 +00:00
mutex = Mutex::createMutex();
}
SimManagerNameDictionary::~SimManagerNameDictionary()
{
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
delete[] hashTable;
#endif
2012-09-19 15:15:01 +00:00
Mutex::destroyMutex(mutex);
}
void SimManagerNameDictionary::insert(SimObject* obj)
{
if(!obj || !obj->objectName)
2012-09-19 15:15:01 +00:00
return;
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
S32 idx = HashPointer(obj->objectName) % hashTableSize;
obj->nextManagerNameObject = hashTable[idx];
hashTable[idx] = obj;
hashEntryCount++;
// Rehash if necessary.
if( hashEntryCount > hashTableSize )
{
// Allocate new table.
U32 newHashTableSize = hashTableSize * 2 + 1;
SimObject** newHashTable = new SimObject *[ newHashTableSize ];
dMemset( newHashTable, 0, sizeof( newHashTable[ 0 ] ) * newHashTableSize );
// Move entries over.
for( U32 i = 0; i < hashTableSize; ++ i )
for( SimObject* object = hashTable[ i ]; object != NULL; )
{
SimObject* next = object->nextManagerNameObject;
idx = HashPointer( object->objectName ) % newHashTableSize;
object->nextManagerNameObject = newHashTable[ idx ];
newHashTable[ idx ] = object;
object = next;
}
// Switch tables.
delete [] hashTable;
hashTable = newHashTable;
hashTableSize = newHashTableSize;
}
#else
root[obj->objectName] = obj;
#endif
2012-09-19 15:15:01 +00:00
Mutex::unlockMutex(mutex);
}
SimObject* SimManagerNameDictionary::find(StringTableEntry name)
{
// NULL is a valid lookup - it will always return NULL
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
S32 idx = HashPointer(name) % hashTableSize;
SimObject *walk = hashTable[idx];
while(walk)
{
if(walk->objectName == name)
{
Mutex::unlockMutex(mutex);
return walk;
}
walk = walk->nextManagerNameObject;
}
Mutex::unlockMutex(mutex);
2012-09-19 15:15:01 +00:00
return NULL;
#else
StringDictDef::iterator it = root.find(name);
SimObject* f = (it == root.end() ? NULL : it->second);
Mutex::unlockMutex(mutex);
return f;
#endif
2012-09-19 15:15:01 +00:00
}
void SimManagerNameDictionary::remove(SimObject* obj)
{
if(!obj || !obj->objectName)
2012-09-19 15:15:01 +00:00
return;
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
Mutex::lockMutex(mutex);
SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize];
while(*walk)
{
if(*walk == obj)
{
*walk = obj->nextManagerNameObject;
2017-01-12 04:34:46 +00:00
obj->nextManagerNameObject = (SimObject*)-1;
2012-09-19 15:15:01 +00:00
hashEntryCount--;
Mutex::unlockMutex(mutex);
return;
}
walk = &((*walk)->nextManagerNameObject);
}
#else
StringTableEntry name = obj->objectName;
if (root.find(name) != root.end())
root.erase(name);
#endif
2012-09-19 15:15:01 +00:00
Mutex::unlockMutex(mutex);
2017-01-12 04:34:46 +00:00
}
2012-09-19 15:15:01 +00:00
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
SimIdDictionary::SimIdDictionary()
{
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
dMemset( table, 0, sizeof( table[ 0 ] ) * DefaultTableSize );
#endif
2012-09-19 15:15:01 +00:00
mutex = Mutex::createMutex();
}
SimIdDictionary::~SimIdDictionary()
{
Mutex::destroyMutex(mutex);
}
2012-09-19 15:15:01 +00:00
void SimIdDictionary::insert(SimObject* obj)
{
if (!obj)
return;
2012-09-19 15:15:01 +00:00
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
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
2012-09-19 15:15:01 +00:00
Mutex::unlockMutex(mutex);
}
SimObject* SimIdDictionary::find(S32 id)
{
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
S32 idx = id & TableBitMask;
SimObject *walk = table[idx];
while(walk)
{
if(walk->getId() == U32(id))
{
Mutex::unlockMutex(mutex);
return walk;
}
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
2012-09-19 15:15:01 +00:00
}
void SimIdDictionary::remove(SimObject* obj)
{
if (!obj)
return;
2012-09-19 15:15:01 +00:00
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
SimObject **walk = &table[obj->getId() & TableBitMask];
while(*walk && *walk != obj)
walk = &((*walk)->nextIdObject);
if(*walk)
*walk = obj->nextIdObject;
#else
root.erase(obj->getId());
#endif
2012-09-19 15:15:01 +00:00
Mutex::unlockMutex(mutex);
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------