simDictionary.cpp 9.5 KB

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