lluuidhashmap_tut.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:10k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file lluuidhashmap_tut.cpp
  3.  * @author Adroit
  4.  * @date 2007-02
  5.  * @brief Test cases for LLUUIDHashMap
  6.  *
  7.  * $LicenseInfo:firstyear=2007&license=viewergpl$
  8.  * 
  9.  * Copyright (c) 2007-2010, Linden Research, Inc.
  10.  * 
  11.  * Second Life Viewer Source Code
  12.  * The source code in this file ("Source Code") is provided by Linden Lab
  13.  * to you under the terms of the GNU General Public License, version 2.0
  14.  * ("GPL"), unless you have obtained a separate licensing agreement
  15.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  16.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18.  * 
  19.  * There are special exceptions to the terms and conditions of the GPL as
  20.  * it is applied to this Source Code. View the full text of the exception
  21.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  22.  * online at
  23.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24.  * 
  25.  * By copying, modifying or distributing this software, you acknowledge
  26.  * that you have read and understood your obligations described above,
  27.  * and agree to abide by those obligations.
  28.  * 
  29.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31.  * COMPLETENESS OR PERFORMANCE.
  32.  * $/LicenseInfo$
  33.  */
  34. #include <tut/tut.hpp>
  35. #include "linden_common.h"
  36. #include "lluuidhashmap.h"
  37. #include "llsdserialize.h"
  38. namespace tut
  39. {
  40. class UUIDTableEntry
  41. {
  42. public:
  43. UUIDTableEntry()
  44. {
  45. mID.setNull();
  46. mValue = 0;
  47. }
  48. UUIDTableEntry(const LLUUID& id, U32 value)
  49. {
  50. mID = id;
  51. mValue = value;
  52. }
  53. ~UUIDTableEntry(){};
  54. static BOOL uuidEq(const LLUUID &uuid, const UUIDTableEntry &id_pair)
  55. {
  56. if (uuid == id_pair.mID)
  57. {
  58. return TRUE;
  59. }
  60. return FALSE;
  61. }
  62. const LLUUID& getID() { return mID; }
  63. const U32& getValue() { return mValue; }
  64. protected:
  65. LLUUID mID;
  66. U32  mValue;
  67. };
  68. struct hashmap_test
  69. {
  70. };
  71. typedef test_group<hashmap_test> hash_index_t;
  72. typedef hash_index_t::object hash_index_object_t;
  73. tut::hash_index_t tut_hash_index("hashmap_test");
  74. // stress test
  75. template<> template<>
  76. void hash_index_object_t::test<1>()
  77. {
  78. LLUUIDHashMap<UUIDTableEntry, 32> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
  79. const int numElementsToCheck = 32*256*32;
  80. std::vector<LLUUID> idList(numElementsToCheck);
  81. int i;
  82. for (i = 0; i < numElementsToCheck; i++)
  83. {
  84. LLUUID id;
  85. id.generate();
  86. UUIDTableEntry entry(id, i);
  87. hashTable.set(id, entry);
  88. idList[i] = id;
  89. }
  90. for (i = 0; i < numElementsToCheck; i++)
  91. {
  92. LLUUID idToCheck = idList[i];
  93. UUIDTableEntry entryToCheck = hashTable.get(idToCheck);
  94. ensure("set/get did not work", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)i);
  95. }
  96. for (i = 0; i < numElementsToCheck; i++)
  97. {
  98. LLUUID idToCheck = idList[i];
  99. if (i % 2 != 0)
  100. {
  101. hashTable.remove(idToCheck);
  102. }
  103. }
  104. for (i = 0; i < numElementsToCheck; i++)
  105. {
  106. LLUUID idToCheck = idList[i];
  107. ensure("remove or check did not work", (i % 2 == 0 && hashTable.check(idToCheck)) || (i % 2 != 0 && !hashTable.check(idToCheck)));
  108. }
  109. }
  110. // test removing all but one element. 
  111. template<> template<>
  112. void hash_index_object_t::test<2>()
  113. {
  114. LLUUIDHashMap<UUIDTableEntry, 2> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
  115. const int numElementsToCheck = 5;
  116. std::vector<LLUUID> idList(numElementsToCheck*10);
  117. int i;
  118. for (i = 0; i < numElementsToCheck; i++)
  119. {
  120. LLUUID id;
  121. id.generate();
  122. UUIDTableEntry entry(id, i);
  123. hashTable.set(id, entry);
  124. idList[i] = id;
  125. }
  126. ensure("getLength failed", hashTable.getLength() == numElementsToCheck);
  127. // remove all but the last element
  128. for (i = 0; i < numElementsToCheck-1; i++)
  129. {
  130. LLUUID idToCheck = idList[i];
  131. hashTable.remove(idToCheck);
  132. }
  133. // there should only be one element left now.
  134. ensure("getLength failed", hashTable.getLength() == 1);
  135. for (i = 0; i < numElementsToCheck; i++)
  136. {
  137. LLUUID idToCheck = idList[i];
  138. if (i != numElementsToCheck - 1)
  139. {
  140. ensure("remove did not work", hashTable.check(idToCheck)  == FALSE);
  141. }
  142. else
  143. {
  144. UUIDTableEntry entryToCheck = hashTable.get(idToCheck);
  145. ensure("remove did not work", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)i);
  146. }
  147. }
  148. }
  149. // test overriding of value already set. 
  150. template<> template<>
  151. void hash_index_object_t::test<3>()
  152. {
  153. LLUUIDHashMap<UUIDTableEntry, 5> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
  154. const int numElementsToCheck = 10;
  155. std::vector<LLUUID> idList(numElementsToCheck);
  156. int i;
  157. for (i = 0; i < numElementsToCheck; i++)
  158. {
  159. LLUUID id;
  160. id.generate();
  161. UUIDTableEntry entry(id, i);
  162. hashTable.set(id, entry);
  163. idList[i] = id;
  164. }
  165. for (i = 0; i < numElementsToCheck; i++)
  166. {
  167. LLUUID id = idList[i];
  168. // set new entry with value = i+numElementsToCheck
  169. UUIDTableEntry entry(id, i+numElementsToCheck);
  170. hashTable.set(id, entry);
  171. }
  172. for (i = 0; i < numElementsToCheck; i++)
  173. {
  174. LLUUID idToCheck = idList[i];
  175. UUIDTableEntry entryToCheck = hashTable.get(idToCheck);
  176. ensure("set/get did not work", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)(i+numElementsToCheck));
  177. }
  178. }
  179. // test removeAll() 
  180. template<> template<>
  181. void hash_index_object_t::test<4>()
  182. {
  183. LLUUIDHashMap<UUIDTableEntry, 5> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
  184. const int numElementsToCheck = 10;
  185. std::vector<LLUUID> idList(numElementsToCheck);
  186. int i;
  187. for (i = 0; i < numElementsToCheck; i++)
  188. {
  189. LLUUID id;
  190. id.generate();
  191. UUIDTableEntry entry(id, i);
  192. hashTable.set(id, entry);
  193. idList[i] = id;
  194. }
  195. hashTable.removeAll();
  196. ensure("removeAll failed", hashTable.getLength() == 0);
  197. }
  198. // test sparse map - force it by creating 256 entries that fall into 256 different nodes 
  199. template<> template<>
  200. void hash_index_object_t::test<5>()
  201. {
  202. LLUUIDHashMap<UUIDTableEntry, 2> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
  203. const int numElementsToCheck = 256;
  204. std::vector<LLUUID> idList(numElementsToCheck);
  205. int i;
  206. for (i = 0; i < numElementsToCheck; i++)
  207. {
  208. LLUUID id;
  209. id.generate();
  210. // LLUUIDHashMap uses mData[0] to pick the bucket
  211. // overwrite mData[0] so that it ranges from 0 to 255
  212. id.mData[0] = i; 
  213. UUIDTableEntry entry(id, i);
  214. hashTable.set(id, entry);
  215. idList[i] = id;
  216. }
  217. for (i = 0; i < numElementsToCheck; i++)
  218. {
  219. LLUUID idToCheck = idList[i];
  220. UUIDTableEntry entryToCheck = hashTable.get(idToCheck);
  221. ensure("set/get did not work for sparse map", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)i);
  222. }
  223. for (i = 0; i < numElementsToCheck; i++)
  224. {
  225. LLUUID idToCheck = idList[i];
  226. if (i % 2 != 0)
  227. {
  228. hashTable.remove(idToCheck);
  229. }
  230. }
  231. for (i = 0; i < numElementsToCheck; i++)
  232. {
  233. LLUUID idToCheck = idList[i];
  234. ensure("remove or check did not work for sparse map", (i % 2 == 0 && hashTable.check(idToCheck)) || (i % 2 != 0 && !hashTable.check(idToCheck)));
  235. }
  236. }
  237. // iterator
  238. template<> template<>
  239. void hash_index_object_t::test<6>()
  240. {
  241. LLUUIDHashMap<UUIDTableEntry, 2> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
  242. LLUUIDHashMapIter<UUIDTableEntry, 2> hashIter(&hashTable);
  243. const int numElementsToCheck = 256;
  244. std::vector<LLUUID> idList(numElementsToCheck);
  245. int i;
  246. for (i = 0; i < numElementsToCheck; i++)
  247. {
  248. LLUUID id;
  249. id.generate();
  250. // LLUUIDHashMap uses mData[0] to pick the bucket
  251. // overwrite mData[0] so that it ranges from 0 to 255
  252. // to create a sparse map
  253. id.mData[0] = i; 
  254. UUIDTableEntry entry(id, i);
  255. hashTable.set(id, entry);
  256. idList[i] = id;
  257. }
  258. hashIter.first();
  259. int numElementsIterated = 0;
  260. while(!hashIter.done())
  261. {
  262. numElementsIterated++;
  263. UUIDTableEntry tableEntry = *hashIter;
  264. LLUUID id = tableEntry.getID();
  265. hashIter.next();
  266. ensure("Iteration failed for sparse map", tableEntry.getValue() < (size_t)numElementsToCheck && idList[tableEntry.getValue()] ==  tableEntry.getID());
  267. }
  268. ensure("iteration count failed", numElementsIterated == numElementsToCheck);
  269. }
  270. // remove after middle of iteration
  271. template<> template<>
  272. void hash_index_object_t::test<7>()
  273. {
  274. LLUUIDHashMap<UUIDTableEntry, 2> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
  275. LLUUIDHashMapIter<UUIDTableEntry, 2> hashIter(&hashTable);
  276. const int numElementsToCheck = 256;
  277. std::vector<LLUUID> idList(numElementsToCheck);
  278. int i;
  279. LLUUID uuidtoSearch;
  280. for (i = 0; i < numElementsToCheck; i++)
  281. {
  282. LLUUID id;
  283. id.generate();
  284. // LLUUIDHashMap uses mData[0] to pick the bucket
  285. // overwrite mData[0] so that it ranges from 0 to 255
  286. // to create a sparse map
  287. id.mData[0] = i; 
  288. UUIDTableEntry entry(id, i);
  289. hashTable.set(id, entry);
  290. idList[i] = id;
  291. // pick uuid somewhere in the middle
  292. if (i == 5)
  293. {
  294. uuidtoSearch = id;
  295. }
  296. }
  297. hashIter.first();
  298. int numElementsIterated = 0;
  299. while(!hashIter.done())
  300. {
  301. numElementsIterated++;
  302. UUIDTableEntry tableEntry = *hashIter;
  303. LLUUID id = tableEntry.getID();
  304. if (uuidtoSearch == id)
  305. {
  306. break;
  307. }
  308. hashIter.next();
  309. }
  310. // current iterator implementation will not allow any remove operations
  311. // until ALL elements have been iterated over. this seems to be 
  312. // an unnecessary restriction. Iterator should have a method to
  313. // reset() its state so that further operations (inckuding remove)
  314. // can be performed on the HashMap without having to iterate thru 
  315. // all the remaining nodes. 
  316. //  hashIter.reset();
  317. //  hashTable.remove(uuidtoSearch);
  318. //  ensure("remove after iteration reset failed", hashTable.check(uuidtoSearch) == FALSE);
  319. }
  320. }