simDictionary.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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 S32 HashPointer(StringTableEntry e);
  27. SimNameDictionary::SimNameDictionary()
  28. {
  29. hashTable = NULL;
  30. mutex = Mutex::createMutex();
  31. }
  32. SimNameDictionary::~SimNameDictionary()
  33. {
  34. delete[] hashTable;
  35. Mutex::destroyMutex(mutex);
  36. }
  37. void SimNameDictionary::insert(SimObject* obj)
  38. {
  39. if(!obj->objectName)
  40. return;
  41. SimObject* checkForDup = find(obj->objectName);
  42. if (checkForDup)
  43. Con::warnf("Warning! You have a duplicate datablock name of %s. This can cause problems. You should rename one of them.", obj->objectName);
  44. Mutex::lockMutex(mutex);
  45. if(!hashTable)
  46. {
  47. hashTable = new SimObject *[DefaultTableSize];
  48. hashTableSize = DefaultTableSize;
  49. hashEntryCount = 0;
  50. dMemset( hashTable, 0, sizeof( *hashTable ) * DefaultTableSize );
  51. }
  52. S32 idx = HashPointer(obj->objectName) % hashTableSize;
  53. obj->nextNameObject = hashTable[idx];
  54. hashTable[idx] = obj;
  55. hashEntryCount++;
  56. // Rehash if necessary.
  57. if( hashEntryCount > hashTableSize )
  58. {
  59. // Allocate new table.
  60. U32 newHashTableSize = hashTableSize * 2 + 1;
  61. SimObject** newHashTable = new SimObject *[ newHashTableSize ];
  62. dMemset( newHashTable, 0, sizeof( newHashTable[ 0 ] ) * newHashTableSize );
  63. // Move entries over.
  64. for( U32 i = 0; i < hashTableSize; ++ i )
  65. for( SimObject* object = hashTable[ i ]; object != NULL; )
  66. {
  67. SimObject* next = object->nextNameObject;
  68. idx = HashPointer( object->objectName ) % newHashTableSize;
  69. object->nextNameObject = newHashTable[ idx ];
  70. newHashTable[ idx ] = object;
  71. object = next;
  72. }
  73. // Switch tables.
  74. delete [] hashTable;
  75. hashTable = newHashTable;
  76. hashTableSize = newHashTableSize;
  77. }
  78. Mutex::unlockMutex(mutex);
  79. }
  80. SimObject* SimNameDictionary::find(StringTableEntry name)
  81. {
  82. // NULL is a valid lookup - it will always return NULL
  83. if(!hashTable)
  84. return NULL;
  85. Mutex::lockMutex(mutex);
  86. S32 idx = HashPointer(name) % hashTableSize;
  87. SimObject *walk = hashTable[idx];
  88. while(walk)
  89. {
  90. if(walk->objectName == name)
  91. {
  92. Mutex::unlockMutex(mutex);
  93. return walk;
  94. }
  95. walk = walk->nextNameObject;
  96. }
  97. Mutex::unlockMutex(mutex);
  98. return NULL;
  99. }
  100. void SimNameDictionary::remove(SimObject* obj)
  101. {
  102. if(!obj->objectName)
  103. return;
  104. Mutex::lockMutex(mutex);
  105. SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize];
  106. while(*walk)
  107. {
  108. if(*walk == obj)
  109. {
  110. *walk = obj->nextNameObject;
  111. obj->nextNameObject = (SimObject*)-1;
  112. hashEntryCount--;
  113. Mutex::unlockMutex(mutex);
  114. return;
  115. }
  116. walk = &((*walk)->nextNameObject);
  117. }
  118. Mutex::unlockMutex(mutex);
  119. }
  120. //----------------------------------------------------------------------------
  121. SimManagerNameDictionary::SimManagerNameDictionary()
  122. {
  123. hashTable = new SimObject *[DefaultTableSize];
  124. hashTableSize = DefaultTableSize;
  125. hashEntryCount = 0;
  126. dMemset( hashTable, 0, sizeof( hashTable[ 0 ] ) * hashTableSize );
  127. mutex = Mutex::createMutex();
  128. }
  129. SimManagerNameDictionary::~SimManagerNameDictionary()
  130. {
  131. delete[] hashTable;
  132. Mutex::destroyMutex(mutex);
  133. }
  134. void SimManagerNameDictionary::insert(SimObject* obj)
  135. {
  136. if(!obj->objectName)
  137. return;
  138. Mutex::lockMutex(mutex);
  139. S32 idx = HashPointer(obj->objectName) % hashTableSize;
  140. obj->nextManagerNameObject = hashTable[idx];
  141. hashTable[idx] = obj;
  142. hashEntryCount++;
  143. // Rehash if necessary.
  144. if( hashEntryCount > hashTableSize )
  145. {
  146. // Allocate new table.
  147. U32 newHashTableSize = hashTableSize * 2 + 1;
  148. SimObject** newHashTable = new SimObject *[ newHashTableSize ];
  149. dMemset( newHashTable, 0, sizeof( newHashTable[ 0 ] ) * newHashTableSize );
  150. // Move entries over.
  151. for( U32 i = 0; i < hashTableSize; ++ i )
  152. for( SimObject* object = hashTable[ i ]; object != NULL; )
  153. {
  154. SimObject* next = object->nextManagerNameObject;
  155. idx = HashPointer( object->objectName ) % newHashTableSize;
  156. object->nextManagerNameObject = newHashTable[ idx ];
  157. newHashTable[ idx ] = object;
  158. object = next;
  159. }
  160. // Switch tables.
  161. delete [] hashTable;
  162. hashTable = newHashTable;
  163. hashTableSize = newHashTableSize;
  164. }
  165. Mutex::unlockMutex(mutex);
  166. }
  167. SimObject* SimManagerNameDictionary::find(StringTableEntry name)
  168. {
  169. // NULL is a valid lookup - it will always return NULL
  170. Mutex::lockMutex(mutex);
  171. S32 idx = HashPointer(name) % hashTableSize;
  172. SimObject *walk = hashTable[idx];
  173. while(walk)
  174. {
  175. if(walk->objectName == name)
  176. {
  177. Mutex::unlockMutex(mutex);
  178. return walk;
  179. }
  180. walk = walk->nextManagerNameObject;
  181. }
  182. Mutex::unlockMutex(mutex);
  183. return NULL;
  184. }
  185. void SimManagerNameDictionary::remove(SimObject* obj)
  186. {
  187. if(!obj->objectName)
  188. return;
  189. Mutex::lockMutex(mutex);
  190. SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize];
  191. while(*walk)
  192. {
  193. if(*walk == obj)
  194. {
  195. *walk = obj->nextManagerNameObject;
  196. obj->nextManagerNameObject = (SimObject*)-1;
  197. hashEntryCount--;
  198. Mutex::unlockMutex(mutex);
  199. return;
  200. }
  201. walk = &((*walk)->nextManagerNameObject);
  202. }
  203. Mutex::unlockMutex(mutex);
  204. }
  205. //---------------------------------------------------------------------------
  206. //---------------------------------------------------------------------------
  207. SimIdDictionary::SimIdDictionary()
  208. {
  209. dMemset( table, 0, sizeof( table[ 0 ] ) * DefaultTableSize );
  210. mutex = Mutex::createMutex();
  211. }
  212. SimIdDictionary::~SimIdDictionary()
  213. {
  214. Mutex::destroyMutex(mutex);
  215. }
  216. void SimIdDictionary::insert(SimObject* obj)
  217. {
  218. Mutex::lockMutex(mutex);
  219. S32 idx = obj->getId() & TableBitMask;
  220. obj->nextIdObject = table[idx];
  221. AssertFatal( obj->nextIdObject != obj, "SimIdDictionary::insert - Creating Infinite Loop linking to self!" );
  222. table[idx] = obj;
  223. Mutex::unlockMutex(mutex);
  224. }
  225. SimObject* SimIdDictionary::find(S32 id)
  226. {
  227. Mutex::lockMutex(mutex);
  228. S32 idx = id & TableBitMask;
  229. SimObject *walk = table[idx];
  230. while(walk)
  231. {
  232. if(walk->getId() == U32(id))
  233. {
  234. Mutex::unlockMutex(mutex);
  235. return walk;
  236. }
  237. walk = walk->nextIdObject;
  238. }
  239. Mutex::unlockMutex(mutex);
  240. return NULL;
  241. }
  242. void SimIdDictionary::remove(SimObject* obj)
  243. {
  244. Mutex::lockMutex(mutex);
  245. SimObject **walk = &table[obj->getId() & TableBitMask];
  246. while(*walk && *walk != obj)
  247. walk = &((*walk)->nextIdObject);
  248. if(*walk)
  249. *walk = obj->nextIdObject;
  250. Mutex::unlockMutex(mutex);
  251. }
  252. //---------------------------------------------------------------------------
  253. //---------------------------------------------------------------------------