simDictionary.cpp
Engine/source/console/simDictionary.cpp
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
