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 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