Нет описания
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

NativeMultiHashMapTests.cs 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. using System;
  2. using NUnit.Framework;
  3. using Unity.Burst;
  4. using Unity.Collections;
  5. using Unity.Collections.LowLevel.Unsafe;
  6. using Unity.Collections.NotBurstCompatible;
  7. using Unity.Collections.Tests;
  8. using Unity.Jobs;
  9. using UnityEngine;
  10. using UnityEngine.TestTools;
  11. #if !UNITY_PORTABLE_TEST_RUNNER
  12. using System.Text.RegularExpressions;
  13. #endif
  14. internal class NativeMultiHashMapTests : CollectionsTestFixture
  15. {
  16. // These tests require:
  17. // - JobsDebugger support for static safety IDs (added in 2020.1)
  18. // - Asserting throws
  19. #if !UNITY_DOTSRUNTIME
  20. [Test, DotsRuntimeIgnore]
  21. public void NativeMultiHashMap_UseAfterFree_UsesCustomOwnerTypeName()
  22. {
  23. var container = new NativeMultiHashMap<int, int>(10, CommonRwdAllocator.Handle);
  24. container.Add(0, 123);
  25. container.Dispose();
  26. Assert.That(() => container.ContainsKey(0),
  27. Throws.Exception.TypeOf<ObjectDisposedException>()
  28. .With.Message.Contains($"The {container.GetType()} has been deallocated"));
  29. }
  30. [BurstCompile(CompileSynchronously = true)]
  31. struct NativeMultiHashMap_CreateAndUseAfterFreeBurst : IJob
  32. {
  33. public void Execute()
  34. {
  35. var container = new NativeMultiHashMap<int, int>(10, Allocator.Temp);
  36. container.Add(0, 17);
  37. container.Dispose();
  38. container.Add(1, 42);
  39. }
  40. }
  41. [Test, DotsRuntimeIgnore]
  42. public void NativeMultiHashMap_CreateAndUseAfterFreeInBurstJob_UsesCustomOwnerTypeName()
  43. {
  44. // Make sure this isn't the first container of this type ever created, so that valid static safety data exists
  45. var container = new NativeMultiHashMap<int, int>(10, CommonRwdAllocator.Handle);
  46. container.Dispose();
  47. var job = new NativeMultiHashMap_CreateAndUseAfterFreeBurst
  48. {
  49. };
  50. // Two things:
  51. // 1. This exception is logged, not thrown; thus, we use LogAssert to detect it.
  52. // 2. Calling write operation after container.Dispose() emits an unintuitive error message. For now, all this test cares about is whether it contains the
  53. // expected type name.
  54. job.Run();
  55. LogAssert.Expect(LogType.Exception,
  56. new Regex($"InvalidOperationException: The {Regex.Escape(container.GetType().ToString())} has been declared as \\[ReadOnly\\] in the job, but you are writing to it"));
  57. }
  58. #endif
  59. [Test]
  60. public void NativeMultiHashMap_IsEmpty()
  61. {
  62. var container = new NativeMultiHashMap<int, int>(0, Allocator.Persistent);
  63. Assert.IsTrue(container.IsEmpty);
  64. container.Add(0, 0);
  65. Assert.IsFalse(container.IsEmpty);
  66. Assert.AreEqual(1, container.Capacity);
  67. ExpectedCount(ref container, 1);
  68. container.Remove(0, 0);
  69. Assert.IsTrue(container.IsEmpty);
  70. container.Add(0, 0);
  71. container.Clear();
  72. Assert.IsTrue(container.IsEmpty);
  73. container.Dispose();
  74. }
  75. [Test]
  76. public void NativeMultiHashMap_CountValuesForKey()
  77. {
  78. var hashMap = new NativeMultiHashMap<int, int>(1, Allocator.Temp);
  79. hashMap.Add(5, 7);
  80. hashMap.Add(6, 9);
  81. hashMap.Add(6, 10);
  82. Assert.AreEqual(1, hashMap.CountValuesForKey(5));
  83. Assert.AreEqual(2, hashMap.CountValuesForKey(6));
  84. Assert.AreEqual(0, hashMap.CountValuesForKey(7));
  85. hashMap.Dispose();
  86. }
  87. [Test]
  88. public void NativeMultiHashMap_RemoveKeyAndValue()
  89. {
  90. var hashMap = new NativeMultiHashMap<int, long>(1, Allocator.Temp);
  91. hashMap.Add(10, 0);
  92. hashMap.Add(10, 1);
  93. hashMap.Add(10, 2);
  94. hashMap.Add(20, 2);
  95. hashMap.Add(20, 2);
  96. hashMap.Add(20, 1);
  97. hashMap.Add(20, 2);
  98. hashMap.Add(20, 1);
  99. hashMap.Remove(10, 1L);
  100. ExpectValues(hashMap, 10, new[] { 0L, 2L });
  101. ExpectValues(hashMap, 20, new[] { 1L, 1L, 2L, 2L, 2L });
  102. hashMap.Remove(20, 2L);
  103. ExpectValues(hashMap, 10, new[] { 0L, 2L });
  104. ExpectValues(hashMap, 20, new[] { 1L, 1L });
  105. hashMap.Remove(20, 1L);
  106. ExpectValues(hashMap, 10, new[] { 0L, 2L });
  107. ExpectValues(hashMap, 20, new long[0]);
  108. hashMap.Dispose();
  109. }
  110. [Test]
  111. public void NativeMultiHashMap_ValueIterator()
  112. {
  113. var hashMap = new NativeMultiHashMap<int, int>(1, Allocator.Temp);
  114. hashMap.Add(5, 0);
  115. hashMap.Add(5, 1);
  116. hashMap.Add(5, 2);
  117. var list = new NativeList<int>(CommonRwdAllocator.Handle);
  118. GCAllocRecorder.ValidateNoGCAllocs(() =>
  119. {
  120. list.Clear();
  121. foreach (var value in hashMap.GetValuesForKey(5))
  122. list.Add(value);
  123. });
  124. list.Sort();
  125. Assert.AreEqual(list.ToArrayNBC(), new int[] { 0, 1, 2 });
  126. foreach (var value in hashMap.GetValuesForKey(6))
  127. Assert.Fail();
  128. list.Dispose();
  129. hashMap.Dispose();
  130. }
  131. [Test]
  132. public void NativeMultiHashMap_RemoveKeyValueDoesntDeallocate()
  133. {
  134. var hashMap = new NativeMultiHashMap<int, int>(1, Allocator.Temp) { { 5, 1 } };
  135. hashMap.Remove(5, 5);
  136. GCAllocRecorder.ValidateNoGCAllocs(() =>
  137. {
  138. hashMap.Remove(5, 1);
  139. });
  140. Assert.IsTrue(hashMap.IsEmpty);
  141. hashMap.Dispose();
  142. }
  143. [Test]
  144. public void NativeMultiHashMap_Double_Deallocate_Throws()
  145. {
  146. var hashMap = new NativeMultiHashMap<int, int>(16, CommonRwdAllocator.Handle);
  147. hashMap.Dispose();
  148. Assert.Throws<ObjectDisposedException>(
  149. () => { hashMap.Dispose(); });
  150. }
  151. static void ExpectedCount<TKey, TValue>(ref NativeMultiHashMap<TKey, TValue> container, int expected)
  152. where TKey : struct, IEquatable<TKey>
  153. where TValue : struct
  154. {
  155. Assert.AreEqual(expected == 0, container.IsEmpty);
  156. Assert.AreEqual(expected, container.Count());
  157. }
  158. [Test]
  159. public void NativeMultiHashMap_RemoveOnEmptyMap_DoesNotThrow()
  160. {
  161. var hashMap = new NativeMultiHashMap<int, int>(0, Allocator.Temp);
  162. Assert.DoesNotThrow(() => hashMap.Remove(0));
  163. Assert.DoesNotThrow(() => hashMap.Remove(-425196));
  164. Assert.DoesNotThrow(() => hashMap.Remove(0, 0));
  165. Assert.DoesNotThrow(() => hashMap.Remove(-425196, 0));
  166. hashMap.Dispose();
  167. }
  168. [Test]
  169. public void NativeMultiHashMap_RemoveFromMultiHashMap()
  170. {
  171. var hashMap = new NativeMultiHashMap<int, int>(16, Allocator.Temp);
  172. int iSquared;
  173. // Make sure inserting values work
  174. for (int i = 0; i < 8; ++i)
  175. hashMap.Add(i, i * i);
  176. for (int i = 0; i < 8; ++i)
  177. hashMap.Add(i, i);
  178. Assert.AreEqual(16, hashMap.Capacity, "HashMap grew larger than expected");
  179. // Make sure reading the inserted values work
  180. for (int i = 0; i < 8; ++i)
  181. {
  182. NativeMultiHashMapIterator<int> it;
  183. Assert.IsTrue(hashMap.TryGetFirstValue(i, out iSquared, out it), "Failed get value from hash table");
  184. Assert.AreEqual(iSquared, i, "Got the wrong value from the hash table");
  185. Assert.IsTrue(hashMap.TryGetNextValue(out iSquared, ref it), "Failed get value from hash table");
  186. Assert.AreEqual(iSquared, i * i, "Got the wrong value from the hash table");
  187. }
  188. for (int rm = 0; rm < 8; ++rm)
  189. {
  190. Assert.AreEqual(2, hashMap.Remove(rm));
  191. NativeMultiHashMapIterator<int> it;
  192. Assert.IsFalse(hashMap.TryGetFirstValue(rm, out iSquared, out it), "Failed to remove value from hash table");
  193. for (int i = rm + 1; i < 8; ++i)
  194. {
  195. Assert.IsTrue(hashMap.TryGetFirstValue(i, out iSquared, out it), "Failed get value from hash table");
  196. Assert.AreEqual(iSquared, i, "Got the wrong value from the hash table");
  197. Assert.IsTrue(hashMap.TryGetNextValue(out iSquared, ref it), "Failed get value from hash table");
  198. Assert.AreEqual(iSquared, i * i, "Got the wrong value from the hash table");
  199. }
  200. }
  201. // Make sure entries were freed
  202. for (int i = 0; i < 8; ++i)
  203. hashMap.Add(i, i * i);
  204. for (int i = 0; i < 8; ++i)
  205. hashMap.Add(i, i);
  206. Assert.AreEqual(16, hashMap.Capacity, "HashMap grew larger than expected");
  207. hashMap.Dispose();
  208. }
  209. void ExpectValues(NativeMultiHashMap<int, long> hashMap, int key, long[] expectedValues)
  210. {
  211. var list = new NativeList<long>(CommonRwdAllocator.Handle);
  212. foreach (var value in hashMap.GetValuesForKey(key))
  213. list.Add(value);
  214. list.Sort();
  215. Assert.AreEqual(list.ToArrayNBC(), expectedValues);
  216. list.Dispose();
  217. }
  218. [Test]
  219. public void NativeMultiHashMap_GetKeys()
  220. {
  221. var container = new NativeMultiHashMap<int, int>(1, Allocator.Temp);
  222. for (int i = 0; i < 30; ++i)
  223. {
  224. container.Add(i, 2 * i);
  225. container.Add(i, 3 * i);
  226. }
  227. var keys = container.GetKeyArray(Allocator.Temp);
  228. #if !NET_DOTS // Tuple is not supported by TinyBCL
  229. var (unique, uniqueLength) = container.GetUniqueKeyArray(Allocator.Temp);
  230. Assert.AreEqual(30, uniqueLength);
  231. #endif
  232. Assert.AreEqual(60, keys.Length);
  233. keys.Sort();
  234. for (int i = 0; i < 30; ++i)
  235. {
  236. Assert.AreEqual(i, keys[i * 2 + 0]);
  237. Assert.AreEqual(i, keys[i * 2 + 1]);
  238. #if !NET_DOTS // Tuple is not supported by TinyBCL
  239. Assert.AreEqual(i, unique[i]);
  240. #endif
  241. }
  242. }
  243. #if !UNITY_DOTSRUNTIME
  244. [Test]
  245. public void NativeMultiHashMap_GetUniqueKeysEmpty()
  246. {
  247. var hashMap = new NativeMultiHashMap<int, int>(1, Allocator.Temp);
  248. var keys = hashMap.GetUniqueKeyArray(Allocator.Temp);
  249. Assert.AreEqual(0, keys.Item1.Length);
  250. Assert.AreEqual(0, keys.Item2);
  251. }
  252. [Test]
  253. public void NativeMultiHashMap_GetUniqueKeys()
  254. {
  255. var hashMap = new NativeMultiHashMap<int, int>(1, Allocator.Temp);
  256. for (int i = 0; i < 30; ++i)
  257. {
  258. hashMap.Add(i, 2 * i);
  259. hashMap.Add(i, 3 * i);
  260. }
  261. var keys = hashMap.GetUniqueKeyArray(Allocator.Temp);
  262. hashMap.Dispose();
  263. Assert.AreEqual(30, keys.Item2);
  264. for (int i = 0; i < 30; ++i)
  265. {
  266. Assert.AreEqual(i, keys.Item1[i]);
  267. }
  268. keys.Item1.Dispose();
  269. }
  270. #endif
  271. [Test]
  272. public void NativeMultiHashMap_GetValues()
  273. {
  274. var hashMap = new NativeMultiHashMap<int, int>(1, Allocator.Temp);
  275. for (int i = 0; i < 30; ++i)
  276. {
  277. hashMap.Add(i, 30 + i);
  278. hashMap.Add(i, 60 + i);
  279. }
  280. var values = hashMap.GetValueArray(Allocator.Temp);
  281. hashMap.Dispose();
  282. Assert.AreEqual(60, values.Length);
  283. values.Sort();
  284. for (int i = 0; i < 60; ++i)
  285. {
  286. Assert.AreEqual(30 + i, values[i]);
  287. }
  288. values.Dispose();
  289. }
  290. [Test]
  291. public void NativeMultiHashMap_ForEach_FixedStringInHashMap()
  292. {
  293. using (var stringList = new NativeList<FixedString32Bytes>(10, Allocator.Persistent) { "Hello", ",", "World", "!" })
  294. {
  295. var container = new NativeMultiHashMap<FixedString128Bytes, float>(50, Allocator.Temp);
  296. var seen = new NativeArray<int>(stringList.Length, Allocator.Temp);
  297. foreach (var str in stringList)
  298. {
  299. container.Add(str, 0);
  300. }
  301. foreach (var pair in container)
  302. {
  303. int index = stringList.IndexOf(pair.Key);
  304. Assert.AreEqual(stringList[index], pair.Key.ToString());
  305. seen[index] = seen[index] + 1;
  306. }
  307. for (int i = 0; i < stringList.Length; i++)
  308. {
  309. Assert.AreEqual(1, seen[i], $"Incorrect value count {stringList[i]}");
  310. }
  311. }
  312. }
  313. [Test]
  314. public void NativeMultiHashMap_ForEach([Values(10, 1000)]int n)
  315. {
  316. var seenKeys = new NativeArray<int>(n, Allocator.Temp);
  317. var seenValues = new NativeArray<int>(n * 2, Allocator.Temp);
  318. using (var container = new NativeMultiHashMap<int, int>(1, Allocator.Temp))
  319. {
  320. for (int i = 0; i < n; ++i)
  321. {
  322. container.Add(i, i);
  323. container.Add(i, i + n);
  324. }
  325. var count = 0;
  326. foreach (var kv in container)
  327. {
  328. if (kv.Value < n)
  329. {
  330. Assert.AreEqual(kv.Key, kv.Value);
  331. }
  332. else
  333. {
  334. Assert.AreEqual(kv.Key + n, kv.Value);
  335. }
  336. seenKeys[kv.Key] = seenKeys[kv.Key] + 1;
  337. seenValues[kv.Value] = seenValues[kv.Value] + 1;
  338. ++count;
  339. }
  340. Assert.AreEqual(container.Count(), count);
  341. for (int i = 0; i < n; i++)
  342. {
  343. Assert.AreEqual(2, seenKeys[i], $"Incorrect key count {i}");
  344. Assert.AreEqual(1, seenValues[i], $"Incorrect value count {i}");
  345. Assert.AreEqual(1, seenValues[i + n], $"Incorrect value count {i + n}");
  346. }
  347. }
  348. }
  349. struct NativeMultiHashMap_ForEach_Job : IJob
  350. {
  351. [ReadOnly]
  352. public NativeMultiHashMap<int, int> Input;
  353. [ReadOnly]
  354. public int Num;
  355. public void Execute()
  356. {
  357. var seenKeys = new NativeArray<int>(Num, Allocator.Temp);
  358. var seenValues = new NativeArray<int>(Num * 2, Allocator.Temp);
  359. var count = 0;
  360. foreach (var kv in Input)
  361. {
  362. if (kv.Value < Num)
  363. {
  364. Assert.AreEqual(kv.Key, kv.Value);
  365. }
  366. else
  367. {
  368. Assert.AreEqual(kv.Key + Num, kv.Value);
  369. }
  370. seenKeys[kv.Key] = seenKeys[kv.Key] + 1;
  371. seenValues[kv.Value] = seenValues[kv.Value] + 1;
  372. ++count;
  373. }
  374. Assert.AreEqual(Input.Count(), count);
  375. for (int i = 0; i < Num; i++)
  376. {
  377. Assert.AreEqual(2, seenKeys[i], $"Incorrect key count {i}");
  378. Assert.AreEqual(1, seenValues[i], $"Incorrect value count {i}");
  379. Assert.AreEqual(1, seenValues[i + Num], $"Incorrect value count {i + Num}");
  380. }
  381. seenKeys.Dispose();
  382. seenValues.Dispose();
  383. }
  384. }
  385. [Test]
  386. public void NativeMultiHashMap_ForEach_From_Job([Values(10, 1000)] int n)
  387. {
  388. using (var container = new NativeMultiHashMap<int, int>(1, CommonRwdAllocator.Handle))
  389. {
  390. for (int i = 0; i < n; ++i)
  391. {
  392. container.Add(i, i);
  393. container.Add(i, i + n);
  394. }
  395. new NativeMultiHashMap_ForEach_Job
  396. {
  397. Input = container,
  398. Num = n,
  399. }.Run();
  400. }
  401. }
  402. [Test]
  403. public void NativeMultiHashMap_ForEach_Throws_When_Modified()
  404. {
  405. using (var container = new NativeMultiHashMap<int, int>(32, CommonRwdAllocator.Handle))
  406. {
  407. for (int i = 0; i < 30; ++i)
  408. {
  409. container.Add(i, 30 + i);
  410. container.Add(i, 60 + i);
  411. }
  412. Assert.Throws<ObjectDisposedException>(() =>
  413. {
  414. foreach (var kv in container)
  415. {
  416. container.Add(10, 10);
  417. }
  418. });
  419. Assert.Throws<ObjectDisposedException>(() =>
  420. {
  421. foreach (var kv in container)
  422. {
  423. container.Remove(1);
  424. }
  425. });
  426. }
  427. }
  428. struct NativeMultiHashMap_ForEachIterator : IJob
  429. {
  430. [ReadOnly]
  431. public NativeMultiHashMap<int, int>.KeyValueEnumerator Iter;
  432. public void Execute()
  433. {
  434. while (Iter.MoveNext())
  435. {
  436. }
  437. }
  438. }
  439. [Test]
  440. public void NativeMultiHashMap_ForEach_Throws_Job_Iterator()
  441. {
  442. using (var container = new NativeMultiHashMap<int, int>(32, CommonRwdAllocator.Handle))
  443. {
  444. var jobHandle = new NativeMultiHashMap_ForEachIterator
  445. {
  446. Iter = container.GetEnumerator()
  447. }.Schedule();
  448. Assert.Throws<InvalidOperationException>(() => { container.Add(1, 1); });
  449. jobHandle.Complete();
  450. }
  451. }
  452. struct ParallelWriteToMultiHashMapJob : IJobParallelFor
  453. {
  454. [WriteOnly]
  455. public NativeMultiHashMap<int, int>.ParallelWriter Writer;
  456. public void Execute(int index)
  457. {
  458. Writer.Add(index, 0);
  459. }
  460. }
  461. [Test]
  462. public void NativeMultiHashMap_ForEach_Throws_When_Modified_From_Job()
  463. {
  464. using (var container = new NativeMultiHashMap<int, int>(32, CommonRwdAllocator.Handle))
  465. {
  466. var iter = container.GetEnumerator();
  467. var jobHandle = new ParallelWriteToMultiHashMapJob
  468. {
  469. Writer = container.AsParallelWriter()
  470. }.Schedule(1, 2);
  471. Assert.Throws<ObjectDisposedException>(() =>
  472. {
  473. while (iter.MoveNext())
  474. {
  475. }
  476. });
  477. jobHandle.Complete();
  478. }
  479. }
  480. #if !UNITY_PORTABLE_TEST_RUNNER // https://unity3d.atlassian.net/browse/DOTSR-1432
  481. [Test]
  482. public void NativeMultiHashMap_GetKeysAndValues()
  483. {
  484. var container = new NativeMultiHashMap<int, int>(1, Allocator.Temp);
  485. for (int i = 0; i < 30; ++i)
  486. {
  487. container.Add(i, 30 + i);
  488. container.Add(i, 60 + i);
  489. }
  490. var keysValues = container.GetKeyValueArrays(Allocator.Temp);
  491. container.Dispose();
  492. Assert.AreEqual(60, keysValues.Keys.Length);
  493. Assert.AreEqual(60, keysValues.Values.Length);
  494. // ensure keys and matching values are aligned (though unordered)
  495. for (int i = 0; i < 30; ++i)
  496. {
  497. var k0 = keysValues.Keys[i * 2 + 0];
  498. var k1 = keysValues.Keys[i * 2 + 1];
  499. var v0 = keysValues.Values[i * 2 + 0];
  500. var v1 = keysValues.Values[i * 2 + 1];
  501. if (v0 > v1)
  502. (v0, v1) = (v1, v0);
  503. Assert.AreEqual(k0, k1);
  504. Assert.AreEqual(30 + k0, v0);
  505. Assert.AreEqual(60 + k0, v1);
  506. }
  507. keysValues.Keys.Sort();
  508. for (int i = 0; i < 30; ++i)
  509. {
  510. Assert.AreEqual(i, keysValues.Keys[i * 2 + 0]);
  511. Assert.AreEqual(i, keysValues.Keys[i * 2 + 1]);
  512. }
  513. keysValues.Values.Sort();
  514. for (int i = 0; i < 60; ++i)
  515. {
  516. Assert.AreEqual(30 + i, keysValues.Values[i]);
  517. }
  518. keysValues.Dispose();
  519. }
  520. #endif
  521. [Test]
  522. public void NativeMultiHashMap_ContainsKeyMultiHashMap()
  523. {
  524. var container = new NativeMultiHashMap<int, int>(1, Allocator.Temp);
  525. container.Add(5, 7);
  526. container.Add(6, 9);
  527. container.Add(6, 10);
  528. Assert.IsTrue(container.ContainsKey(5));
  529. Assert.IsTrue(container.ContainsKey(6));
  530. Assert.IsFalse(container.ContainsKey(4));
  531. container.Dispose();
  532. }
  533. [Test]
  534. public void NativeMultiHashMap_CustomAllocatorTest()
  535. {
  536. AllocatorManager.Initialize();
  537. var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent);
  538. ref var allocator = ref allocatorHelper.Allocator;
  539. allocator.Initialize();
  540. using (var container = new NativeMultiHashMap<int, int>(1, allocator.Handle))
  541. {
  542. }
  543. Assert.IsTrue(allocator.WasUsed);
  544. allocator.Dispose();
  545. allocatorHelper.Dispose();
  546. AllocatorManager.Shutdown();
  547. }
  548. [BurstCompile]
  549. struct BurstedCustomAllocatorJob : IJob
  550. {
  551. [NativeDisableUnsafePtrRestriction]
  552. public unsafe CustomAllocatorTests.CountingAllocator* Allocator;
  553. public void Execute()
  554. {
  555. unsafe
  556. {
  557. using (var container = new NativeMultiHashMap<int, int>(1, Allocator->Handle))
  558. {
  559. }
  560. }
  561. }
  562. }
  563. [Test]
  564. public unsafe void NativeMultiHashMap_BurstedCustomAllocatorTest()
  565. {
  566. AllocatorManager.Initialize();
  567. var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent);
  568. ref var allocator = ref allocatorHelper.Allocator;
  569. allocator.Initialize();
  570. var allocatorPtr = (CustomAllocatorTests.CountingAllocator*)UnsafeUtility.AddressOf<CustomAllocatorTests.CountingAllocator>(ref allocator);
  571. unsafe
  572. {
  573. var handle = new BurstedCustomAllocatorJob {Allocator = allocatorPtr}.Schedule();
  574. handle.Complete();
  575. }
  576. Assert.IsTrue(allocator.WasUsed);
  577. allocator.Dispose();
  578. allocatorHelper.Dispose();
  579. AllocatorManager.Shutdown();
  580. }
  581. }