SparseArray.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include "tests/framework/Framework.h"
  6. #include <anki/util/SparseArray.h>
  7. #include <unordered_map>
  8. ANKI_TEST(Util, SparseArray)
  9. {
  10. HeapAllocator<U8> alloc(allocAligned, nullptr);
  11. // Set same key
  12. {
  13. SparseArray<PtrSize> arr;
  14. arr.setAt(alloc, 1000, 123);
  15. auto it = arr.setAt(alloc, 1000, 124);
  16. ANKI_TEST_EXPECT_EQ(*arr.getAt(1000), 124);
  17. arr.erase(alloc, it);
  18. }
  19. // Check destroy
  20. {
  21. SparseArray<PtrSize> arr;
  22. arr.setAt(alloc, 10000, 123);
  23. arr.setAt(alloc, 20000, 124);
  24. arr.setAt(alloc, 30000, 125);
  25. ANKI_TEST_EXPECT_EQ(*arr.getAt(10000), 123);
  26. ANKI_TEST_EXPECT_EQ(*arr.getAt(20000), 124);
  27. ANKI_TEST_EXPECT_EQ(*arr.getAt(30000), 125);
  28. arr.destroy(alloc);
  29. }
  30. // Do complex insertions
  31. {
  32. SparseArray<PtrSize, U32, 32, 3> arr;
  33. arr.setAt(alloc, 32, 1);
  34. // Linear probing
  35. arr.setAt(alloc, 32 * 2, 2);
  36. arr.setAt(alloc, 32 * 3, 3);
  37. // Append to a tree
  38. arr.setAt(alloc, 32 * 4, 4);
  39. // Linear probing
  40. arr.setAt(alloc, 32 + 1, 5);
  41. // Evict node
  42. arr.setAt(alloc, 32 * 2 + 1, 5);
  43. ANKI_TEST_EXPECT_EQ(arr.getSize(), 6);
  44. arr.destroy(alloc);
  45. }
  46. // Fuzzy test
  47. {
  48. const U MAX = 1000;
  49. SparseArray<int, U32, 32, 3> arr;
  50. std::vector<int> numbers;
  51. srand(time(nullptr));
  52. // Insert random
  53. for(U i = 0; i < MAX; ++i)
  54. {
  55. U num;
  56. while(1)
  57. {
  58. num = rand();
  59. if(std::find(numbers.begin(), numbers.end(), int(num)) == numbers.end())
  60. {
  61. // Not found
  62. ANKI_TEST_EXPECT_EQ(arr.getAt(num), arr.getEnd());
  63. arr.setAt(alloc, num, num);
  64. numbers.push_back(num);
  65. break;
  66. }
  67. else
  68. {
  69. // Found
  70. ANKI_TEST_EXPECT_NEQ(arr.getAt(num), arr.getEnd());
  71. }
  72. }
  73. }
  74. ANKI_TEST_EXPECT_EQ(arr.getSize(), MAX);
  75. // Remove randomly
  76. U count = MAX;
  77. while(count--)
  78. {
  79. U idx = rand() % (count + 1);
  80. int num = numbers[idx];
  81. numbers.erase(numbers.begin() + idx);
  82. auto it = arr.getAt(num);
  83. ANKI_TEST_EXPECT_NEQ(it, arr.getEnd());
  84. ANKI_TEST_EXPECT_EQ(*it, num);
  85. arr.erase(alloc, it);
  86. }
  87. }
  88. // Fuzzy test #2: Do random insertions and removals
  89. {
  90. const U MAX = 1000;
  91. SparseArray<int, U32, 64, 4> arr;
  92. using StlMap =
  93. std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, HeapAllocator<std::pair<int, int>>>;
  94. StlMap map(10, std::hash<int>(), std::equal_to<int>(), alloc);
  95. for(U i = 0; i < MAX; ++i)
  96. {
  97. Bool insert = (rand() & 1) || arr.getSize() == 0;
  98. if(insert)
  99. {
  100. I idx = rand();
  101. arr.setAt(alloc, idx, idx);
  102. map[idx] = idx;
  103. }
  104. else
  105. {
  106. auto it = std::next(std::begin(map), rand() % map.size());
  107. auto it2 = arr.getAt(it->second);
  108. ANKI_TEST_EXPECT_NEQ(it2, arr.getEnd());
  109. map.erase(it);
  110. arr.erase(alloc, it2);
  111. }
  112. }
  113. arr.destroy(alloc);
  114. }
  115. }