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   hashTableSize = DefaultTableSize;
 36   hashEntryCount = 0;
 37#endif
 38   mutex = Mutex::createMutex();
 39}
 40
 41SimNameDictionary::~SimNameDictionary()
 42{
 43#ifndef USE_NEW_SIMDICTIONARY
 44   delete[] hashTable;
 45#endif
 46   Mutex::destroyMutex(mutex);
 47}
 48
 49void SimNameDictionary::insert(SimObject* obj)
 50{
 51   if (!obj || !obj->getName())
 52      return;
 53
 54   SimObject* checkForDup = find(obj->getName());
 55
 56   if (checkForDup)
 57      Con::warnf("Warning! You have a duplicate datablock name of %s. This can cause problems. You should rename one of them.", obj->getName());
 58
 59   Mutex::lockMutex(mutex);
 60#ifndef USE_NEW_SIMDICTIONARY
 61   if (!hashTable)
 62   {
 63      hashTable = new SimObject *[DefaultTableSize];
 64      hashTableSize = DefaultTableSize;
 65      hashEntryCount = 0;
 66
 67      dMemset(hashTable, 0, sizeof(*hashTable) * DefaultTableSize);
 68   }
 69
 70   S32 idx = HashPointer(obj->getName()) % hashTableSize;
 71   obj->nextNameObject = hashTable[idx];
 72   hashTable[idx] = obj;
 73   hashEntryCount++;
 74
 75   // Rehash if necessary.
 76
 77   if (hashEntryCount > hashTableSize)
 78   {
 79      // Allocate new table.
 80
 81      U32 newHashTableSize = hashTableSize * 2 + 1;
 82      SimObject** newHashTable = new SimObject *[newHashTableSize];
 83      dMemset(newHashTable, 0, sizeof(newHashTable[0]) * newHashTableSize);
 84
 85      // Move entries over.
 86
 87      for (U32 i = 0; i < hashTableSize; ++i)
 88         for (SimObject* object = hashTable[i]; object != NULL; )
 89         {
 90            SimObject* next = object->nextNameObject;
 91
 92            idx = HashPointer(object->getName()) % newHashTableSize;
 93            object->nextNameObject = newHashTable[idx];
 94            newHashTable[idx] = object;
 95
 96            object = next;
 97         }
 98
 99      // Switch tables.
100
101      delete[] hashTable;
102      hashTable = newHashTable;
103      hashTableSize = newHashTableSize;
104   }
105#else
106   root[obj->objectName] = obj;
107#endif
108   Mutex::unlockMutex(mutex);
109}
110
111SimObject* SimNameDictionary::find(StringTableEntry name)
112{
113#ifndef USE_NEW_SIMDICTIONARY
114   // NULL is a valid lookup - it will always return NULL
115   if (!hashTable)
116      return NULL;
117
118   Mutex::lockMutex(mutex);
119
120   S32 idx = HashPointer(name) % hashTableSize;
121   SimObject *walk = hashTable[idx];
122   while (walk)
123   {
124      if (walk->getName() == name)
125      {
126         Mutex::unlockMutex(mutex);
127         return walk;
128      }
129      walk = walk->nextNameObject;
130   }
131
132   Mutex::unlockMutex(mutex);
133   return NULL;
134#else
135   Mutex::lockMutex(mutex);
136   StringDictDef::iterator it = root.find(name);
137   SimObject* f = (it == root.end() ? NULL : it->second);
138   Mutex::unlockMutex(mutex);
139   return f;
140#endif
141}
142
143void SimNameDictionary::remove(SimObject* obj)
144{
145   if (!obj || !obj->getName())
146      return;
147
148   Mutex::lockMutex(mutex);
149#ifndef USE_NEW_SIMDICTIONARY
150   SimObject **walk = &hashTable[HashPointer(obj->getName()) % hashTableSize];
151   while (*walk)
152   {
153      if (*walk == obj)
154      {
155         *walk = obj->nextNameObject;
156         obj->nextNameObject = nullptr;
157         hashEntryCount--;
158
159         Mutex::unlockMutex(mutex);
160         return;
161      }
162      walk = &((*walk)->nextNameObject);
163   }
164#else
165   const char* name = obj->objectName;
166   if (root.find(name) != root.end())
167      root.erase(name);
168#endif
169   Mutex::unlockMutex(mutex);
170}
171
172//----------------------------------------------------------------------------
173
174SimManagerNameDictionary::SimManagerNameDictionary()
175{
176#ifndef USE_NEW_SIMDICTIONARY
177   hashTable = new SimObject *[DefaultTableSize];
178   hashTableSize = DefaultTableSize;
179   hashEntryCount = 0;
180
181   dMemset(hashTable, 0, sizeof(hashTable[0]) * hashTableSize);
182#endif
183   mutex = Mutex::createMutex();
184}
185
186SimManagerNameDictionary::~SimManagerNameDictionary()
187{
188#ifndef USE_NEW_SIMDICTIONARY
189   delete[] hashTable;
190#endif
191   Mutex::destroyMutex(mutex);
192}
193
194void SimManagerNameDictionary::insert(SimObject* obj)
195{
196   if (!obj || !obj->getName())
197      return;
198
199   Mutex::lockMutex(mutex);
200#ifndef USE_NEW_SIMDICTIONARY
201   S32 idx = HashPointer(obj->getName()) % hashTableSize;
202   obj->nextManagerNameObject = hashTable[idx];
203   hashTable[idx] = obj;
204   hashEntryCount++;
205
206   // Rehash if necessary.
207
208   if (hashEntryCount > hashTableSize)
209   {
210      // Allocate new table.
211
212      U32 newHashTableSize = hashTableSize * 2 + 1;
213      SimObject** newHashTable = new SimObject *[newHashTableSize];
214      dMemset(newHashTable, 0, sizeof(newHashTable[0]) * newHashTableSize);
215
216      // Move entries over.
217
218      for (U32 i = 0; i < hashTableSize; ++i)
219         for (SimObject* object = hashTable[i]; object != NULL; )
220         {
221            SimObject* next = object->nextManagerNameObject;
222
223            idx = HashPointer(object->getName()) % newHashTableSize;
224            object->nextManagerNameObject = newHashTable[idx];
225            newHashTable[idx] = object;
226
227            object = next;
228         }
229
230      // Switch tables.
231
232      delete[] hashTable;
233      hashTable = newHashTable;
234      hashTableSize = newHashTableSize;
235   }
236#else
237   root[obj->objectName] = obj;
238#endif
239   Mutex::unlockMutex(mutex);
240}
241
242SimObject* SimManagerNameDictionary::find(StringTableEntry name)
243{
244   // NULL is a valid lookup - it will always return NULL
245
246   Mutex::lockMutex(mutex);
247
248#ifndef USE_NEW_SIMDICTIONARY
249   S32 idx = HashPointer(name) % hashTableSize;
250   SimObject *walk = hashTable[idx];
251   while (walk)
252   {
253      if (walk->getName() == name)
254      {
255         Mutex::unlockMutex(mutex);
256         return walk;
257      }
258      walk = walk->nextManagerNameObject;
259   }
260   Mutex::unlockMutex(mutex);
261
262   return NULL;
263#else
264   StringDictDef::iterator it = root.find(name);
265   SimObject* f = (it == root.end() ? NULL : it->second);
266   Mutex::unlockMutex(mutex);
267   return f;
268#endif
269}
270
271void SimManagerNameDictionary::remove(SimObject* obj)
272{
273   if (!obj || !obj->getName())
274      return;
275
276#ifndef USE_NEW_SIMDICTIONARY
277   Mutex::lockMutex(mutex);
278
279   SimObject **walk = &hashTable[HashPointer(obj->getName()) % hashTableSize];
280   while (*walk)
281   {
282      if (*walk == obj)
283      {
284         *walk = obj->nextManagerNameObject;
285         obj->nextManagerNameObject = nullptr;
286         hashEntryCount--;
287
288         Mutex::unlockMutex(mutex);
289         return;
290      }
291      walk = &((*walk)->nextManagerNameObject);
292   }
293#else
294   StringTableEntry name = obj->objectName;
295   if (root.find(name) != root.end())
296      root.erase(name);
297#endif
298   Mutex::unlockMutex(mutex);
299}
300
301//---------------------------------------------------------------------------
302//---------------------------------------------------------------------------
303
304SimIdDictionary::SimIdDictionary()
305{
306#ifndef USE_NEW_SIMDICTIONARY
307   dMemset(table, 0, sizeof(table[0]) * DefaultTableSize);
308#endif
309   mutex = Mutex::createMutex();
310}
311
312SimIdDictionary::~SimIdDictionary()
313{
314   Mutex::destroyMutex(mutex);
315}
316
317
318
319void SimIdDictionary::insert(SimObject* obj)
320{
321   if (!obj)
322      return;
323
324   Mutex::lockMutex(mutex);
325#ifndef USE_NEW_SIMDICTIONARY
326   S32 idx = obj->getId() & TableBitMask;
327   obj->nextIdObject = table[idx];
328   AssertFatal(obj->nextIdObject != obj, "SimIdDictionary::insert - Creating Infinite Loop linking to self!");
329   table[idx] = obj;
330#else
331   root[obj->getId()] = obj;
332#endif
333   Mutex::unlockMutex(mutex);
334}
335
336SimObject* SimIdDictionary::find(S32 id)
337{
338   Mutex::lockMutex(mutex);
339#ifndef USE_NEW_SIMDICTIONARY
340   S32 idx = id & TableBitMask;
341   SimObject *walk = table[idx];
342   while (walk)
343   {
344      if (walk->getId() == U32(id))
345      {
346         Mutex::unlockMutex(mutex);
347         return walk;
348      }
349      walk = walk->nextIdObject;
350   }
351   Mutex::unlockMutex(mutex);
352
353   return NULL;
354#else
355   SimObjectIdDictDef::iterator it = root.find(id);
356   SimObject* f = (it == root.end() ? NULL : it->second);
357   Mutex::unlockMutex(mutex);
358   return f;
359#endif
360}
361
362void SimIdDictionary::remove(SimObject* obj)
363{
364   if (!obj)
365      return;
366
367   Mutex::lockMutex(mutex);
368#ifndef USE_NEW_SIMDICTIONARY
369   SimObject **walk = &table[obj->getId() & TableBitMask];
370   while (*walk && *walk != obj)
371      walk = &((*walk)->nextIdObject);
372   if (*walk)
373      *walk = obj->nextIdObject;
374#else
375   root.erase(obj->getId());
376#endif
377   Mutex::unlockMutex(mutex);
378}
379
380//---------------------------------------------------------------------------
381//---------------------------------------------------------------------------
382
383