simDictionary.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  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 || !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[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. StringDictDef::iterator it = root.find(name);
  111. SimObject* f = (it == root.end() ? NULL : it->second);
  112. Mutex::unlockMutex(mutex);
  113. return f;
  114. #endif
  115. }
  116. void SimNameDictionary::remove(SimObject* obj)
  117. {
  118. if(!obj || !obj->objectName)
  119. return;
  120. Mutex::lockMutex(mutex);
  121. #ifndef USE_NEW_SIMDICTIONARY
  122. SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize];
  123. while(*walk)
  124. {
  125. if(*walk == obj)
  126. {
  127. *walk = obj->nextNameObject;
  128. obj->nextNameObject = (SimObject*)-1;
  129. hashEntryCount--;
  130. Mutex::unlockMutex(mutex);
  131. return;
  132. }
  133. walk = &((*walk)->nextNameObject);
  134. }
  135. #else
  136. const char* name = obj->objectName;
  137. if (root.find(name) != root.end())
  138. root.erase(name);
  139. #endif
  140. Mutex::unlockMutex(mutex);
  141. }
  142. //----------------------------------------------------------------------------
  143. SimManagerNameDictionary::SimManagerNameDictionary()
  144. {
  145. #ifndef USE_NEW_SIMDICTIONARY
  146. hashTable = new SimObject *[DefaultTableSize];
  147. hashTableSize = DefaultTableSize;
  148. hashEntryCount = 0;
  149. dMemset( hashTable, 0, sizeof( hashTable[ 0 ] ) * hashTableSize );
  150. #endif
  151. mutex = Mutex::createMutex();
  152. }
  153. SimManagerNameDictionary::~SimManagerNameDictionary()
  154. {
  155. #ifndef USE_NEW_SIMDICTIONARY
  156. delete[] hashTable;
  157. #endif
  158. Mutex::destroyMutex(mutex);
  159. }
  160. void SimManagerNameDictionary::insert(SimObject* obj)
  161. {
  162. if(!obj || !obj->objectName)
  163. return;
  164. Mutex::lockMutex(mutex);
  165. #ifndef USE_NEW_SIMDICTIONARY
  166. S32 idx = HashPointer(obj->objectName) % hashTableSize;
  167. obj->nextManagerNameObject = hashTable[idx];
  168. hashTable[idx] = obj;
  169. hashEntryCount++;
  170. // Rehash if necessary.
  171. if( hashEntryCount > hashTableSize )
  172. {
  173. // Allocate new table.
  174. U32 newHashTableSize = hashTableSize * 2 + 1;
  175. SimObject** newHashTable = new SimObject *[ newHashTableSize ];
  176. dMemset( newHashTable, 0, sizeof( newHashTable[ 0 ] ) * newHashTableSize );
  177. // Move entries over.
  178. for( U32 i = 0; i < hashTableSize; ++ i )
  179. for( SimObject* object = hashTable[ i ]; object != NULL; )
  180. {
  181. SimObject* next = object->nextManagerNameObject;
  182. idx = HashPointer( object->objectName ) % newHashTableSize;
  183. object->nextManagerNameObject = newHashTable[ idx ];
  184. newHashTable[ idx ] = object;
  185. object = next;
  186. }
  187. // Switch tables.
  188. delete [] hashTable;
  189. hashTable = newHashTable;
  190. hashTableSize = newHashTableSize;
  191. }
  192. #else
  193. root[obj->objectName] = obj;
  194. #endif
  195. Mutex::unlockMutex(mutex);
  196. }
  197. SimObject* SimManagerNameDictionary::find(StringTableEntry name)
  198. {
  199. // NULL is a valid lookup - it will always return NULL
  200. Mutex::lockMutex(mutex);
  201. #ifndef USE_NEW_SIMDICTIONARY
  202. S32 idx = HashPointer(name) % hashTableSize;
  203. SimObject *walk = hashTable[idx];
  204. while(walk)
  205. {
  206. if(walk->objectName == name)
  207. {
  208. Mutex::unlockMutex(mutex);
  209. return walk;
  210. }
  211. walk = walk->nextManagerNameObject;
  212. }
  213. Mutex::unlockMutex(mutex);
  214. return NULL;
  215. #else
  216. StringDictDef::iterator it = root.find(name);
  217. SimObject* f = (it == root.end() ? NULL : it->second);
  218. Mutex::unlockMutex(mutex);
  219. return f;
  220. #endif
  221. }
  222. void SimManagerNameDictionary::remove(SimObject* obj)
  223. {
  224. if(!obj || !obj->objectName)
  225. return;
  226. #ifndef USE_NEW_SIMDICTIONARY
  227. Mutex::lockMutex(mutex);
  228. SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize];
  229. while(*walk)
  230. {
  231. if(*walk == obj)
  232. {
  233. *walk = obj->nextManagerNameObject;
  234. obj->nextManagerNameObject = (SimObject*)-1;
  235. hashEntryCount--;
  236. Mutex::unlockMutex(mutex);
  237. return;
  238. }
  239. walk = &((*walk)->nextManagerNameObject);
  240. }
  241. #else
  242. StringTableEntry name = obj->objectName;
  243. if (root.find(name) != root.end())
  244. root.erase(name);
  245. #endif
  246. Mutex::unlockMutex(mutex);
  247. }
  248. //---------------------------------------------------------------------------
  249. //---------------------------------------------------------------------------
  250. SimIdDictionary::SimIdDictionary()
  251. {
  252. #ifndef USE_NEW_SIMDICTIONARY
  253. dMemset( table, 0, sizeof( table[ 0 ] ) * DefaultTableSize );
  254. #endif
  255. mutex = Mutex::createMutex();
  256. }
  257. SimIdDictionary::~SimIdDictionary()
  258. {
  259. Mutex::destroyMutex(mutex);
  260. }
  261. void SimIdDictionary::insert(SimObject* obj)
  262. {
  263. if (!obj)
  264. return;
  265. Mutex::lockMutex(mutex);
  266. #ifndef USE_NEW_SIMDICTIONARY
  267. S32 idx = obj->getId() & TableBitMask;
  268. obj->nextIdObject = table[idx];
  269. AssertFatal( obj->nextIdObject != obj, "SimIdDictionary::insert - Creating Infinite Loop linking to self!" );
  270. table[idx] = obj;
  271. #else
  272. root[obj->getId()] = obj;
  273. #endif
  274. Mutex::unlockMutex(mutex);
  275. }
  276. SimObject* SimIdDictionary::find(S32 id)
  277. {
  278. Mutex::lockMutex(mutex);
  279. #ifndef USE_NEW_SIMDICTIONARY
  280. S32 idx = id & TableBitMask;
  281. SimObject *walk = table[idx];
  282. while(walk)
  283. {
  284. if(walk->getId() == U32(id))
  285. {
  286. Mutex::unlockMutex(mutex);
  287. return walk;
  288. }
  289. walk = walk->nextIdObject;
  290. }
  291. Mutex::unlockMutex(mutex);
  292. return NULL;
  293. #else
  294. SimObjectIdDictDef::iterator it = root.find(id);
  295. SimObject* f = (it == root.end() ? NULL : it->second);
  296. Mutex::unlockMutex(mutex);
  297. return f;
  298. #endif
  299. }
  300. void SimIdDictionary::remove(SimObject* obj)
  301. {
  302. if (!obj)
  303. return;
  304. Mutex::lockMutex(mutex);
  305. #ifndef USE_NEW_SIMDICTIONARY
  306. SimObject **walk = &table[obj->getId() & TableBitMask];
  307. while(*walk && *walk != obj)
  308. walk = &((*walk)->nextIdObject);
  309. if(*walk)
  310. *walk = obj->nextIdObject;
  311. #else
  312. root.erase(obj->getId());
  313. #endif
  314. Mutex::unlockMutex(mutex);
  315. }
  316. //---------------------------------------------------------------------------
  317. //---------------------------------------------------------------------------