Torque3D Documentation / _generateds / simDictionary.cpp

simDictionary.cpp

Engine/source/console/simDictionary.cpp

More...

Public Functions

Detailed Description

Public Functions

HashPointer(StringTableEntry e)

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "console/simDictionary.h"
 25#include "console/simBase.h"
 26
 27//----------------------------------------------------------------------------
 28//----------------------------------------------------------------------------
 29extern U32 HashPointer(StringTableEntry e);
 30
 31SimNameDictionary::SimNameDictionary()
 32{
 33#ifndef USE_NEW_SIMDICTIONARY
 34   hashTable = NULL;
 35#endif
 36   mutex = Mutex::createMutex();
 37}
 38
 39SimNameDictionary::~SimNameDictionary()
 40{
 41#ifndef USE_NEW_SIMDICTIONARY
 42   delete[] hashTable;
 43#endif
 44   Mutex::destroyMutex(mutex);
 45}
 46
 47void SimNameDictionary::insert(SimObject* obj)
 48{
 49   if(!obj || !obj->objectName)
 50      return;
 51
 52   SimObject* checkForDup = find(obj->objectName);
 53
 54   if (checkForDup)
 55      Con::warnf("Warning! You have a duplicate datablock name of %s. This can cause problems. You should rename one of them.", obj->objectName);
 56
 57   Mutex::lockMutex(mutex);
 58#ifndef USE_NEW_SIMDICTIONARY
 59   if(!hashTable)
 60   {
 61      hashTable = new SimObject *[DefaultTableSize];
 62      hashTableSize = DefaultTableSize;
 63      hashEntryCount = 0;
 64      
 65      dMemset( hashTable, 0, sizeof( *hashTable ) * DefaultTableSize );
 66   }
 67   
 68   S32 idx = HashPointer(obj->objectName) % hashTableSize;
 69   obj->nextNameObject = hashTable[idx];
 70   hashTable[idx] = obj;
 71   hashEntryCount++;
 72   
 73   // Rehash if necessary.
 74
 75   if( hashEntryCount > hashTableSize )
 76   {
 77      // Allocate new table.
 78      
 79      U32 newHashTableSize = hashTableSize * 2 + 1;
 80      SimObject** newHashTable = new SimObject *[ newHashTableSize ];
 81      dMemset( newHashTable, 0, sizeof( newHashTable[ 0 ] ) * newHashTableSize );
 82      
 83      // Move entries over.
 84
 85      for( U32 i = 0; i < hashTableSize; ++ i )
 86         for( SimObject* object = hashTable[ i ]; object != NULL; )
 87         {
 88            SimObject* next = object->nextNameObject;
 89
 90            idx = HashPointer( object->objectName ) % newHashTableSize;
 91            object->nextNameObject = newHashTable[ idx ];
 92            newHashTable[ idx ] = object;
 93            
 94            object = next;
 95         }
 96         
 97      // Switch tables.
 98      
 99      delete [] hashTable;
100      hashTable = newHashTable;
101      hashTableSize = newHashTableSize;
102   }
103#else
104   root[obj->objectName] = obj;
105#endif
106   Mutex::unlockMutex(mutex);
107}
108
109SimObject* SimNameDictionary::find(StringTableEntry name)
110{
111#ifndef USE_NEW_SIMDICTIONARY
112   // NULL is a valid lookup - it will always return NULL
113   if(!hashTable)
114      return NULL;
115      
116   Mutex::lockMutex(mutex);
117
118   S32 idx = HashPointer(name) % hashTableSize;
119   SimObject *walk = hashTable[idx];
120   while(walk)
121   {
122      if(walk->objectName == name)
123      {
124         Mutex::unlockMutex(mutex);
125         return walk;
126      }
127      walk = walk->nextNameObject;
128   }
129
130   Mutex::unlockMutex(mutex);
131   return NULL;
132#else
133  Mutex::lockMutex(mutex);
134  StringDictDef::iterator it = root.find(name);
135  SimObject* f = (it == root.end() ? NULL : it->second);
136  Mutex::unlockMutex(mutex);
137  return f;
138#endif
139}
140
141void SimNameDictionary::remove(SimObject* obj)
142{
143   if(!obj || !obj->objectName)
144      return;
145
146   Mutex::lockMutex(mutex);
147#ifndef USE_NEW_SIMDICTIONARY
148   SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize];
149   while(*walk)
150   {
151      if(*walk == obj)
152      {
153         *walk = obj->nextNameObject;
154         obj->nextNameObject = (SimObject*)-1;
155         hashEntryCount--;
156
157         Mutex::unlockMutex(mutex);
158         return;
159      }
160      walk = &((*walk)->nextNameObject);
161   }
162#else
163   const char* name = obj->objectName;
164   if (root.find(name) != root.end())
165      root.erase(name);
166#endif
167   Mutex::unlockMutex(mutex);
168}  
169
170//----------------------------------------------------------------------------
171
172SimManagerNameDictionary::SimManagerNameDictionary()
173{
174#ifndef USE_NEW_SIMDICTIONARY
175   hashTable = new SimObject *[DefaultTableSize];
176   hashTableSize = DefaultTableSize;
177   hashEntryCount = 0;
178   
179   dMemset( hashTable, 0, sizeof( hashTable[ 0 ] ) * hashTableSize );
180#endif
181   mutex = Mutex::createMutex();
182}
183
184SimManagerNameDictionary::~SimManagerNameDictionary()
185{
186#ifndef USE_NEW_SIMDICTIONARY
187   delete[] hashTable;
188#endif
189   Mutex::destroyMutex(mutex);
190}
191
192void SimManagerNameDictionary::insert(SimObject* obj)
193{
194   if(!obj || !obj->objectName)
195      return;
196
197   Mutex::lockMutex(mutex);
198#ifndef USE_NEW_SIMDICTIONARY
199   S32 idx = HashPointer(obj->objectName) % hashTableSize;
200   obj->nextManagerNameObject = hashTable[idx];
201   hashTable[idx] = obj;
202   hashEntryCount++;
203   
204   // Rehash if necessary.
205
206   if( hashEntryCount > hashTableSize )
207   {
208      // Allocate new table.
209      
210      U32 newHashTableSize = hashTableSize * 2 + 1;
211      SimObject** newHashTable = new SimObject *[ newHashTableSize ];
212      dMemset( newHashTable, 0, sizeof( newHashTable[ 0 ] ) * newHashTableSize );
213      
214      // Move entries over.
215
216      for( U32 i = 0; i < hashTableSize; ++ i )
217         for( SimObject* object = hashTable[ i ]; object != NULL; )
218         {
219            SimObject* next = object->nextManagerNameObject;
220
221            idx = HashPointer( object->objectName ) % newHashTableSize;
222            object->nextManagerNameObject = newHashTable[ idx ];
223            newHashTable[ idx ] = object;
224            
225            object = next;
226         }
227         
228      // Switch tables.
229      
230      delete [] hashTable;
231      hashTable = newHashTable;
232      hashTableSize = newHashTableSize;
233   }
234#else
235   root[obj->objectName] = obj;
236#endif
237   Mutex::unlockMutex(mutex);
238}
239
240SimObject* SimManagerNameDictionary::find(StringTableEntry name)
241{
242   // NULL is a valid lookup - it will always return NULL
243
244   Mutex::lockMutex(mutex);
245
246#ifndef USE_NEW_SIMDICTIONARY
247   S32 idx = HashPointer(name) % hashTableSize;
248   SimObject *walk = hashTable[idx];
249   while(walk)
250   {
251      if(walk->objectName == name)
252      {
253         Mutex::unlockMutex(mutex);
254         return walk;
255      }
256      walk = walk->nextManagerNameObject;
257   }
258   Mutex::unlockMutex(mutex);
259
260   return NULL;
261#else
262   StringDictDef::iterator it = root.find(name);
263   SimObject* f = (it == root.end() ? NULL : it->second);
264   Mutex::unlockMutex(mutex);
265   return f;
266#endif
267}
268
269void SimManagerNameDictionary::remove(SimObject* obj)
270{
271   if(!obj || !obj->objectName)
272      return;
273
274#ifndef USE_NEW_SIMDICTIONARY
275   Mutex::lockMutex(mutex);
276
277   SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize];
278   while(*walk)
279   {
280      if(*walk == obj)
281      {
282         *walk = obj->nextManagerNameObject;
283         obj->nextManagerNameObject = (SimObject*)-1;
284         hashEntryCount--;
285
286         Mutex::unlockMutex(mutex);
287         return;
288      }
289      walk = &((*walk)->nextManagerNameObject);
290   }
291#else
292   StringTableEntry name = obj->objectName;
293   if (root.find(name) != root.end())
294      root.erase(name);
295#endif
296   Mutex::unlockMutex(mutex);
297}  
298
299//---------------------------------------------------------------------------
300//---------------------------------------------------------------------------
301
302SimIdDictionary::SimIdDictionary()
303{
304#ifndef USE_NEW_SIMDICTIONARY
305   dMemset( table, 0, sizeof( table[ 0 ] ) * DefaultTableSize );
306#endif
307   mutex = Mutex::createMutex();
308}
309
310SimIdDictionary::~SimIdDictionary()
311{
312   Mutex::destroyMutex(mutex);
313}
314
315
316
317void SimIdDictionary::insert(SimObject* obj)
318{
319   if (!obj)
320      return;
321
322   Mutex::lockMutex(mutex);
323#ifndef USE_NEW_SIMDICTIONARY
324   S32 idx = obj->getId() & TableBitMask;
325   obj->nextIdObject = table[idx];
326   AssertFatal( obj->nextIdObject != obj, "SimIdDictionary::insert - Creating Infinite Loop linking to self!" );
327   table[idx] = obj;
328#else
329   root[obj->getId()] = obj;
330#endif
331   Mutex::unlockMutex(mutex);
332}
333
334SimObject* SimIdDictionary::find(S32 id)
335{
336   Mutex::lockMutex(mutex);
337#ifndef USE_NEW_SIMDICTIONARY
338   S32 idx = id & TableBitMask;
339   SimObject *walk = table[idx];
340   while(walk)
341   {
342      if(walk->getId() == U32(id))
343      {
344         Mutex::unlockMutex(mutex);
345         return walk;
346      }
347      walk = walk->nextIdObject;
348   }
349   Mutex::unlockMutex(mutex);
350
351   return NULL;
352#else
353   SimObjectIdDictDef::iterator it = root.find(id);
354   SimObject* f = (it == root.end() ? NULL : it->second);
355   Mutex::unlockMutex(mutex);
356   return f;
357#endif
358}
359
360void SimIdDictionary::remove(SimObject* obj)
361{
362   if (!obj)
363      return;
364
365   Mutex::lockMutex(mutex);
366#ifndef USE_NEW_SIMDICTIONARY
367   SimObject **walk = &table[obj->getId() & TableBitMask];
368   while(*walk && *walk != obj)
369      walk = &((*walk)->nextIdObject);
370   if(*walk)
371      *walk = obj->nextIdObject;
372#else
373   root.erase(obj->getId());
374#endif
375   Mutex::unlockMutex(mutex);
376}
377
378//---------------------------------------------------------------------------
379//---------------------------------------------------------------------------
380
381