Brak opisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UnsafeBitArrayTests.cs 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. using NUnit.Framework;
  2. using System;
  3. using Unity.Burst;
  4. using Unity.Collections;
  5. using Unity.Collections.LowLevel.Unsafe;
  6. using Unity.Jobs;
  7. using Unity.Mathematics;
  8. using Assert = FastAssert;
  9. namespace Unity.Collections.Tests
  10. {
  11. internal class UnsafeBitArrayTests
  12. {
  13. [Test]
  14. public void UnsafeBitArray_Init()
  15. {
  16. var container = new UnsafeBitArray(0, Allocator.Persistent, NativeArrayOptions.ClearMemory);
  17. Assert.True(container.IsCreated);
  18. Assert.True(container.IsEmpty);
  19. Assert.DoesNotThrow(() => container.Dispose());
  20. }
  21. [Test]
  22. public void UnsafeBitArray_Get_Set_Long()
  23. {
  24. var numBits = 256;
  25. var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
  26. Assert.False(test.IsSet(123));
  27. test.Set(123, true);
  28. Assert.True(test.IsSet(123));
  29. Assert.False(test.TestAll(0, numBits));
  30. Assert.False(test.TestNone(0, numBits));
  31. Assert.True(test.TestAny(0, numBits));
  32. Assert.AreEqual(1, test.CountBits(0, numBits));
  33. Assert.False(test.TestAll(0, 122));
  34. Assert.True(test.TestNone(0, 122));
  35. Assert.False(test.TestAny(0, 122));
  36. test.Clear();
  37. Assert.False(test.IsSet(123));
  38. Assert.AreEqual(0, test.CountBits(0, numBits));
  39. test.SetBits(40, true, 4);
  40. Assert.AreEqual(4, test.CountBits(0, numBits));
  41. test.SetBits(0, true, numBits);
  42. Assert.False(test.TestNone(0, numBits));
  43. Assert.True(test.TestAll(0, numBits));
  44. test.SetBits(0, false, numBits);
  45. Assert.True(test.TestNone(0, numBits));
  46. Assert.False(test.TestAll(0, numBits));
  47. test.SetBits(123, true, 7);
  48. Assert.True(test.TestAll(123, 7));
  49. test.Clear();
  50. test.SetBits(64, true, 64);
  51. Assert.AreEqual(false, test.IsSet(63));
  52. Assert.AreEqual(true, test.TestAll(64, 64));
  53. Assert.AreEqual(false, test.IsSet(128));
  54. Assert.AreEqual(64, test.CountBits(64, 64));
  55. Assert.AreEqual(64, test.CountBits(0, numBits));
  56. test.Clear();
  57. test.SetBits(65, true, 62);
  58. Assert.AreEqual(false, test.IsSet(64));
  59. Assert.AreEqual(true, test.TestAll(65, 62));
  60. Assert.AreEqual(false, test.IsSet(127));
  61. Assert.AreEqual(62, test.CountBits(64, 64));
  62. Assert.AreEqual(62, test.CountBits(0, numBits));
  63. test.Clear();
  64. test.SetBits(66, true, 64);
  65. Assert.AreEqual(false, test.IsSet(65));
  66. Assert.AreEqual(true, test.TestAll(66, 64));
  67. Assert.AreEqual(false, test.IsSet(130));
  68. Assert.AreEqual(64, test.CountBits(66, 64));
  69. Assert.AreEqual(64, test.CountBits(0, numBits));
  70. test.Dispose();
  71. }
  72. [Test]
  73. public void UnsafeBitArray_Get_Set_Short()
  74. {
  75. var numBits = 31;
  76. var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
  77. Assert.False(test.IsSet(13));
  78. test.Set(13, true);
  79. Assert.True(test.IsSet(13));
  80. Assert.False(test.TestAll(0, numBits));
  81. Assert.False(test.TestNone(0, numBits));
  82. Assert.True(test.TestAny(0, numBits));
  83. Assert.AreEqual(1, test.CountBits(0, numBits));
  84. Assert.False(test.TestAll(0, 12));
  85. Assert.True(test.TestNone(0, 12));
  86. Assert.False(test.TestAny(0, 12));
  87. test.Clear();
  88. Assert.False(test.IsSet(13));
  89. Assert.AreEqual(0, test.CountBits(0, numBits));
  90. test.SetBits(4, true, 4);
  91. Assert.AreEqual(4, test.CountBits(0, numBits));
  92. test.SetBits(0, true, numBits);
  93. Assert.False(test.TestNone(0, numBits));
  94. Assert.True(test.TestAll(0, numBits));
  95. test.SetBits(0, false, numBits);
  96. Assert.True(test.TestNone(0, numBits));
  97. Assert.False(test.TestAll(0, numBits));
  98. test.SetBits(13, true, 7);
  99. Assert.True(test.TestAll(13, 7));
  100. test.Clear();
  101. test.SetBits(4, true, 4);
  102. Assert.AreEqual(false, test.IsSet(3));
  103. Assert.AreEqual(true, test.TestAll(4, 4));
  104. Assert.AreEqual(false, test.IsSet(18));
  105. Assert.AreEqual(4, test.CountBits(4, 4));
  106. Assert.AreEqual(4, test.CountBits(0, numBits));
  107. test.Clear();
  108. test.SetBits(5, true, 2);
  109. Assert.AreEqual(false, test.IsSet(4));
  110. Assert.AreEqual(true, test.TestAll(5, 2));
  111. Assert.AreEqual(false, test.IsSet(17));
  112. Assert.AreEqual(2, test.CountBits(4, 4));
  113. Assert.AreEqual(2, test.CountBits(0, numBits));
  114. test.Clear();
  115. test.SetBits(6, true, 4);
  116. Assert.AreEqual(false, test.IsSet(5));
  117. Assert.AreEqual(true, test.TestAll(6, 4));
  118. Assert.AreEqual(false, test.IsSet(10));
  119. Assert.AreEqual(4, test.CountBits(6, 4));
  120. Assert.AreEqual(4, test.CountBits(0, numBits));
  121. test.Dispose();
  122. }
  123. [Test]
  124. public void UnsafeBitArray_Get_Set_Tiny()
  125. {
  126. var numBits = 7;
  127. var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
  128. Assert.False(test.IsSet(3));
  129. test.Set(3, true);
  130. Assert.True(test.IsSet(3));
  131. Assert.False(test.TestAll(0, numBits));
  132. Assert.False(test.TestNone(0, numBits));
  133. Assert.True(test.TestAny(0, numBits));
  134. Assert.AreEqual(1, test.CountBits(0, numBits));
  135. Assert.False(test.TestAll(0, 2));
  136. Assert.True(test.TestNone(0, 2));
  137. Assert.False(test.TestAny(0, 2));
  138. test.Clear();
  139. Assert.False(test.IsSet(3));
  140. Assert.AreEqual(0, test.CountBits(0, numBits));
  141. test.SetBits(3, true, 4);
  142. Assert.AreEqual(4, test.CountBits(0, numBits));
  143. test.SetBits(0, true, numBits);
  144. Assert.False(test.TestNone(0, numBits));
  145. Assert.True(test.TestAll(0, numBits));
  146. test.SetBits(0, false, numBits);
  147. Assert.True(test.TestNone(0, numBits));
  148. Assert.False(test.TestAll(0, numBits));
  149. test.Dispose();
  150. }
  151. [Test]
  152. [TestRequiresDotsDebugOrCollectionChecks]
  153. public unsafe void UnsafeBitArray_Throws()
  154. {
  155. var numBits = 256;
  156. using (var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory))
  157. {
  158. Assert.DoesNotThrow(() => { test.TestAll(0, numBits); });
  159. Assert.DoesNotThrow(() => { test.TestAny(numBits - 1, numBits); });
  160. Assert.Throws<ArgumentException>(() => { test.IsSet(-1); });
  161. Assert.Throws<ArgumentException>(() => { test.IsSet(numBits); });
  162. Assert.Throws<ArgumentException>(() => { test.TestAny(0, 0); });
  163. Assert.Throws<ArgumentException>(() => { test.TestAny(numBits, 1); });
  164. Assert.Throws<ArgumentException>(() => { test.TestAny(numBits - 1, 0); });
  165. // GetBits numBits must be 1-64.
  166. Assert.Throws<ArgumentException>(() => { test.GetBits(0, 0); });
  167. Assert.Throws<ArgumentException>(() => { test.GetBits(0, 65); });
  168. Assert.DoesNotThrow(() => { test.GetBits(63, 2); });
  169. Assert.Throws<ArgumentException>(() => { new UnsafeBitArray(null, 7); /* check sizeInBytes must be multiple of 8-bytes. */ });
  170. }
  171. }
  172. static void GetBitsTest(ref UnsafeBitArray test, int pos, int numBits)
  173. {
  174. test.SetBits(pos, true, numBits);
  175. Assert.AreEqual(numBits, test.CountBits(0, test.Length));
  176. Assert.AreEqual(0xfffffffffffffffful >> (64 - numBits), test.GetBits(pos, numBits));
  177. test.Clear();
  178. }
  179. [Test]
  180. public void UnsafeBitArray_GetBits()
  181. {
  182. var numBits = 256;
  183. var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
  184. GetBitsTest(ref test, 0, 5);
  185. GetBitsTest(ref test, 1, 3);
  186. GetBitsTest(ref test, 0, 63);
  187. GetBitsTest(ref test, 0, 64);
  188. GetBitsTest(ref test, 1, 63);
  189. GetBitsTest(ref test, 1, 64);
  190. GetBitsTest(ref test, 62, 5);
  191. GetBitsTest(ref test, 127, 3);
  192. GetBitsTest(ref test, 250, 6);
  193. GetBitsTest(ref test, 254, 2);
  194. test.Dispose();
  195. }
  196. static void SetBitsTest(ref UnsafeBitArray test, int pos, ulong value, int numBits)
  197. {
  198. test.SetBits(pos, value, numBits);
  199. Assert.AreEqual(value, test.GetBits(pos, numBits));
  200. test.Clear();
  201. }
  202. [Test]
  203. public void UnsafeBitArray_SetBits()
  204. {
  205. var numBits = 256;
  206. var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
  207. SetBitsTest(ref test, 0, 16, 5);
  208. SetBitsTest(ref test, 1, 7, 3);
  209. SetBitsTest(ref test, 1, 32, 64);
  210. SetBitsTest(ref test, 62, 6, 5);
  211. SetBitsTest(ref test, 127, 1, 3);
  212. SetBitsTest(ref test, 60, 0xaa, 8);
  213. test.Dispose();
  214. }
  215. static void CopyBitsTest(ref UnsafeBitArray dstBitArray, int dstPos, ref UnsafeBitArray srcBitArray, int srcPos, int numBits)
  216. {
  217. for (int pos = 0; pos < dstBitArray.Length; pos += 64)
  218. {
  219. dstBitArray.SetBits(pos, 0xaaaaaaaaaaaaaaaaul, 64);
  220. }
  221. srcBitArray.SetBits(srcPos, true, numBits);
  222. dstBitArray.Copy(dstPos, ref srcBitArray, srcPos, numBits);
  223. Assert.AreEqual(true, dstBitArray.TestAll(dstPos, numBits));
  224. for (int pos = 0; pos < dstBitArray.Length; ++pos)
  225. {
  226. if ((pos >= dstPos && pos < dstPos + numBits) ||
  227. (pos >= srcPos && pos < srcPos + numBits))
  228. {
  229. Assert.AreEqual(true, dstBitArray.IsSet(pos));
  230. }
  231. else
  232. {
  233. Assert.AreEqual((0 != (pos & 1)), dstBitArray.IsSet(pos));
  234. }
  235. }
  236. dstBitArray.Clear();
  237. }
  238. static void CopyBitsTest(ref UnsafeBitArray test, int dstPos, int srcPos, int numBits)
  239. {
  240. CopyBitsTest(ref test, dstPos, ref test, srcPos, numBits);
  241. }
  242. static void CopyBitsTests(ref UnsafeBitArray test)
  243. {
  244. CopyBitsTest(ref test, 1, 16, 12); // short up to 64-bits copy
  245. CopyBitsTest(ref test, 1, 80, 63); // short up to 64-bits copy
  246. CopyBitsTest(ref test, 1, 11, 12); // short up to 64-bits copy overlapped
  247. CopyBitsTest(ref test, 11, 1, 12); // short up to 64-bits copy overlapped
  248. CopyBitsTest(ref test, 1, 16, 76); // short up to 128-bits copy
  249. CopyBitsTest(ref test, 1, 80, 127); // short up to 128-bits copy
  250. CopyBitsTest(ref test, 1, 11, 76); // short up to 128-bits copy overlapped
  251. CopyBitsTest(ref test, 11, 1, 76); // short up to 128-bits copy overlapped
  252. CopyBitsTest(ref test, 1, 81, 255); // long copy aligned
  253. CopyBitsTest(ref test, 8, 0, 255); // long copy overlapped aligned
  254. CopyBitsTest(ref test, 1, 80, 255); // long copy unaligned
  255. CopyBitsTest(ref test, 80, 1, 255); // long copy overlapped unaligned
  256. }
  257. [Test]
  258. public void UnsafeBitArray_Copy()
  259. {
  260. var numBits = 512;
  261. var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
  262. CopyBitsTests(ref test);
  263. test.Dispose();
  264. }
  265. [Test]
  266. public void UnsafeBitArray_Resize()
  267. {
  268. var test = new UnsafeBitArray(1, Allocator.Persistent, NativeArrayOptions.ClearMemory);
  269. Assert.AreEqual(1, test.Length);
  270. Assert.AreEqual(64, test.Capacity);
  271. test.SetCapacity(200); // expand
  272. Assert.AreEqual(1, test.Length);
  273. Assert.AreEqual(256, test.Capacity);
  274. test.Resize(100, NativeArrayOptions.ClearMemory);
  275. Assert.True(test.TestNone(0, test.Length));
  276. // prepare survival test
  277. test.Set(0, true);
  278. test.Set(99, true);
  279. Assert.True(test.IsSet(0));
  280. Assert.True(test.TestNone(1, 98));
  281. Assert.True(test.IsSet(99));
  282. test.SetCapacity(1000); // expand
  283. Assert.AreEqual(100, test.Length);
  284. Assert.AreEqual(1024, test.Capacity);
  285. // test resize survival
  286. Assert.True(test.IsSet(0));
  287. Assert.True(test.TestNone(1, 98));
  288. Assert.True(test.IsSet(99));
  289. // manual clear
  290. test.Resize(1);
  291. test.Set(0, false);
  292. test.SetCapacity(200); // truncate capacity
  293. Assert.AreEqual(1, test.Length);
  294. Assert.AreEqual(256, test.Capacity);
  295. test.Resize(512, NativeArrayOptions.ClearMemory); // resize
  296. Assert.AreEqual(512, test.Length);
  297. Assert.AreEqual(512, test.Capacity);
  298. Assert.True(test.TestNone(0, test.Length));
  299. CopyBitsTests(ref test);
  300. test.Resize(256); // truncate length
  301. Assert.AreEqual(256, test.Length);
  302. Assert.AreEqual(512, test.Capacity);
  303. test.TrimExcess();
  304. Assert.AreEqual(256, test.Length);
  305. Assert.AreEqual(256, test.Capacity);
  306. test.Dispose();
  307. }
  308. [Test]
  309. public void UnsafeBitArray_CopyBetweenBitArrays()
  310. {
  311. var numBits = 512;
  312. var test0 = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
  313. var test1 = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
  314. var test2 = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
  315. for (int pos = 0; pos < test0.Length; pos += 64)
  316. {
  317. test0.SetBits(pos, 0xaaaaaaaaaaaaaaaaul, 64);
  318. test1.SetBits(pos, 0x5555555555555555ul, 64);
  319. }
  320. var numCopyBits = 255;
  321. test0.SetBits(13, true, numCopyBits);
  322. test1.Copy(1, ref test0, 13, numCopyBits);
  323. Assert.AreEqual(true, test1.TestAll(1, numCopyBits));
  324. test2.Copy(43, ref test1, 1, numCopyBits);
  325. Assert.AreEqual(true, test2.TestAll(43, numCopyBits));
  326. test0.Dispose();
  327. test1.Dispose();
  328. test2.Dispose();
  329. }
  330. [Test]
  331. [TestRequiresDotsDebugOrCollectionChecks]
  332. public unsafe void UnsafeBitArray_Copy_Throws()
  333. {
  334. var numBits = 512;
  335. var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
  336. Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, 0, numBits - 1, 16); }); // short up to 64-bits copy out of bounds
  337. Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, numBits - 1, 0, 16); }); // short up to 64-bits copy out of bounds
  338. Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, 0, numBits - 1, 80); }); // short up to 128-bits copy out of bounds
  339. Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, numBits - 1, 0, 80); }); // short up to 128-bits copy out of bounds
  340. Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, 1, numBits - 7, 127); }); // long copy aligned
  341. Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, numBits - 7, 1, 127); }); // long copy aligned
  342. Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, 2, numBits - 1, 127); }); // long copy unaligned
  343. Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, numBits - 1, 2, 127); }); // long copy unaligned
  344. test.Dispose();
  345. }
  346. [Test]
  347. public unsafe void UnsafeBitArray_Find()
  348. {
  349. var numBits = 512;
  350. using (var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory))
  351. {
  352. test.SetBits(0, true, 11);
  353. for (var i = 0; i < 256; ++i)
  354. {
  355. Assert.AreEqual(11, test.Find(0, i + 1));
  356. }
  357. for (var j = 0; j < 64; ++j)
  358. {
  359. for (var i = 0; i < 256; ++i)
  360. {
  361. var numBitsToFind = 7 + i;
  362. var pos = 37 + j;
  363. test.SetBits(0, true, test.Length);
  364. test.SetBits(pos, false, numBitsToFind);
  365. Assert.AreEqual(pos, test.Find(0, numBitsToFind), $"{j}/{i}: pos {pos}, numBitsToFind {numBitsToFind}");
  366. Assert.AreEqual(pos, test.Find(pos, numBitsToFind), $"{j}/{i}:pos {pos}, numBitsToFind {numBitsToFind}");
  367. Assert.AreEqual(pos, test.Find(0, numBitsToFind), $"{j}/{i}: pos {pos}, numBitsToFind {numBitsToFind}");
  368. Assert.AreEqual(pos, test.Find(pos, numBitsToFind), $"{j}/{i}: pos {pos}, numBitsToFind {numBitsToFind}");
  369. Assert.IsTrue(test.TestNone(test.Find(0, numBitsToFind), numBitsToFind));
  370. Assert.AreEqual(int.MaxValue, test.Find(pos + 1, numBitsToFind), $"{j}/{i}: pos {pos}, numBitsToFind {numBitsToFind}");
  371. }
  372. }
  373. }
  374. }
  375. [Test]
  376. public unsafe void UnsafeBitArray_Find_With_Begin_End()
  377. {
  378. var numBits = 512;
  379. using (var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory))
  380. {
  381. Assert.AreEqual(0, test.Find(0, 2, 1));
  382. Assert.AreEqual(1, test.Find(1, 2, 1));
  383. test.SetBits(0, true, 6);
  384. Assert.AreEqual(int.MaxValue, test.Find(0, 2, 1));
  385. for (var j = 0; j < 64; ++j)
  386. {
  387. for (var i = 0; i < 256; ++i)
  388. {
  389. var numBitsToFind = 7 + i;
  390. var padding = 11;
  391. var begin = 37 + j;
  392. var end = begin + padding + numBitsToFind;
  393. var count = end - begin;
  394. test.Clear();
  395. test.SetBits(begin, true, count);
  396. test.SetBits(begin + padding + 1, false, numBitsToFind - 1);
  397. Assert.AreEqual(begin + padding + 1, test.Find(begin, count, numBitsToFind - 1)); //, $"{j}/{i}: begin {begin}, end {end}, count {count}, numBitsToFind {numBitsToFind}");
  398. Assert.AreEqual(int.MaxValue, test.Find(begin, count, numBitsToFind)); //, $"{j}/{i}: begin {begin}, end {end}, count {count}, numBitsToFind {numBitsToFind}");
  399. }
  400. }
  401. }
  402. }
  403. [Test]
  404. [TestRequiresDotsDebugOrCollectionChecks]
  405. public unsafe void UnsafeBitArray_Find_Throws()
  406. {
  407. var numBits = 512;
  408. using (var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory))
  409. {
  410. Assert.Throws<ArgumentException>(() => { test.Find(0, 0, 1); }); // empty range
  411. Assert.Throws<ArgumentException>(() => { test.Find(0, 1, 0); }); // zero bits
  412. Assert.Throws<ArgumentException>(() => { test.Find(0, 1, 2); }); // numBits is larger than range
  413. Assert.Throws<ArgumentException>(() => { test.Find(10, 0, 0); }); // empty range, numBits is less than 1
  414. Assert.Throws<ArgumentException>(() => { test.Find(1, 10, -2); }); // numBits can't be negative
  415. }
  416. }
  417. void findWithPattern(ref UnsafeBitArray test, byte pattern, int numBits)
  418. {
  419. for (int pos = 0; pos < test.Length; pos += 8)
  420. {
  421. test.SetBits(pos, pattern, 8);
  422. }
  423. var bitCount = math.countbits((int)pattern);
  424. var numEmptyBits = test.Length - (test.Length / 8 * bitCount);
  425. for (int i = 0; i < numEmptyBits; i += numBits)
  426. {
  427. var pos = test.Find(0, numBits);
  428. Assert.AreNotEqual(int.MaxValue, pos, $"{i}");
  429. test.SetBits(pos, true, numBits);
  430. }
  431. Assert.True(test.TestAll(0, test.Length));
  432. }
  433. [Test]
  434. public void UnsafeBitArray_FindWithPattern()
  435. {
  436. var test = new UnsafeBitArray(512, Allocator.Persistent, NativeArrayOptions.ClearMemory);
  437. // Separated test for some more interesting patterns
  438. findWithPattern(ref test, 0x81, 1);
  439. findWithPattern(ref test, 0x81, 2);
  440. findWithPattern(ref test, 0x81, 3);
  441. findWithPattern(ref test, 0x81, 6);
  442. findWithPattern(ref test, 0x88, 3);
  443. findWithPattern(ref test, 0x99, 2);
  444. findWithPattern(ref test, 0xaa, 1);
  445. findWithPattern(ref test, 0xc3, 1);
  446. findWithPattern(ref test, 0xc3, 2);
  447. findWithPattern(ref test, 0xc3, 4);
  448. findWithPattern(ref test, 0xe7, 1);
  449. findWithPattern(ref test, 0xe7, 2);
  450. // Test all patterns
  451. for (int i = 0; i < 256; i++)
  452. {
  453. findWithPattern(ref test, (byte)i, 1);
  454. }
  455. test.Dispose();
  456. }
  457. [Test]
  458. public void UnsafeBitArray_FindInTinyBitArray()
  459. {
  460. var test = new UnsafeBitArray(3, Allocator.Persistent, NativeArrayOptions.ClearMemory);
  461. Assert.AreEqual(3, test.Length);
  462. test.SetBits(0, 0x55, test.Length);
  463. Assert.AreEqual(1, test.Find(0, 1));
  464. Assert.AreEqual(1, test.Find(0, test.Length, 1));
  465. test.SetBits(1, true, 1);
  466. Assert.True(test.TestAll(0, test.Length));
  467. Assert.AreEqual(int.MaxValue, test.Find(0, test.Length, 1));
  468. test.Dispose();
  469. }
  470. [Test]
  471. public void UnsafeBitArray_FindLastUnsetBit([NUnit.Framework.Range(1, 64)] int numBits)
  472. {
  473. using (var bits = new UnsafeBitArray(numBits, Allocator.Persistent))
  474. {
  475. // Set all bits to one then unset a single bit to find.
  476. for (int i = 0; i < numBits; ++i)
  477. {
  478. bits.SetBits(0, true, numBits);
  479. bits.Set(i, false);
  480. Assert.AreEqual(i, bits.Find(0, 1));
  481. }
  482. }
  483. }
  484. [Test]
  485. public void UnsafeBitArray_CustomAllocatorTest()
  486. {
  487. AllocatorManager.Initialize();
  488. var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent);
  489. ref var allocator = ref allocatorHelper.Allocator;
  490. allocator.Initialize();
  491. using (var container = new UnsafeBitArray(1, allocator.Handle))
  492. {
  493. }
  494. Assert.IsTrue(allocator.WasUsed);
  495. allocator.Dispose();
  496. allocatorHelper.Dispose();
  497. AllocatorManager.Shutdown();
  498. }
  499. [BurstCompile]
  500. struct BurstedCustomAllocatorJob : IJob
  501. {
  502. [NativeDisableUnsafePtrRestriction]
  503. public unsafe CustomAllocatorTests.CountingAllocator* Allocator;
  504. public void Execute()
  505. {
  506. unsafe
  507. {
  508. using (var container = new UnsafeBitArray(1, Allocator->Handle))
  509. {
  510. }
  511. }
  512. }
  513. }
  514. [Test]
  515. public unsafe void UnsafeBitArray_BurstedCustomAllocatorTest()
  516. {
  517. AllocatorManager.Initialize();
  518. var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent);
  519. ref var allocator = ref allocatorHelper.Allocator;
  520. allocator.Initialize();
  521. var allocatorPtr = (CustomAllocatorTests.CountingAllocator*)UnsafeUtility.AddressOf<CustomAllocatorTests.CountingAllocator>(ref allocator);
  522. unsafe
  523. {
  524. var handle = new BurstedCustomAllocatorJob { Allocator = allocatorPtr }.Schedule();
  525. handle.Complete();
  526. }
  527. Assert.IsTrue(allocator.WasUsed);
  528. allocator.Dispose();
  529. allocatorHelper.Dispose();
  530. AllocatorManager.Shutdown();
  531. }
  532. }
  533. }