handle_test.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * Copyright 2010-2025 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
  4. */
  5. #include "test.h"
  6. #include <bx/handlealloc.h>
  7. #include <bx/hash.h>
  8. #include <bx/rng.h>
  9. #include <set>
  10. TEST_CASE("HandleAllocT", "")
  11. {
  12. constexpr int32_t kMax = 64;
  13. bx::HandleAllocT<kMax> alloc;
  14. REQUIRE(sizeof(alloc) == sizeof(uint16_t) * kMax * 2 + sizeof(bx::HandleAlloc) );
  15. for (uint16_t ii = 0; ii < kMax; ++ii)
  16. {
  17. REQUIRE(!alloc.isValid(ii) );
  18. }
  19. bx::RngMwc random;
  20. std::set<uint16_t> handleSet;
  21. int32_t count = 0;
  22. for (int32_t ii = 0; ii < 200000; ++ii)
  23. {
  24. const bool add = random.gen() % 2;
  25. if (add && count < kMax)
  26. {
  27. count++;
  28. uint16_t handle = alloc.alloc();
  29. handleSet.insert(handle);
  30. }
  31. else if (count > 0)
  32. {
  33. count--;
  34. const int32_t idx = rand() % handleSet.size();
  35. auto it = handleSet.begin();
  36. for (int32_t it_idx = 0; it_idx < idx; ++it_idx)
  37. {
  38. it++;
  39. REQUIRE(alloc.isValid(*it) );
  40. }
  41. uint16_t handleToRemove = *it;
  42. alloc.free(handleToRemove);
  43. REQUIRE(!alloc.isValid(handleToRemove) );
  44. handleSet.erase(it);
  45. }
  46. // Check if it's still correct
  47. for (auto it = handleSet.begin(); it != handleSet.end(); ++it)
  48. {
  49. REQUIRE(alloc.isValid(*it) );
  50. }
  51. }
  52. // Finally delete all
  53. for (auto it = handleSet.begin(); it != handleSet.end(); ++it)
  54. {
  55. REQUIRE(alloc.isValid(*it) );
  56. alloc.free(*it);
  57. }
  58. handleSet.clear();
  59. for (uint16_t ii = 0; ii < kMax; ++ii)
  60. {
  61. REQUIRE(!alloc.isValid(ii) );
  62. }
  63. }
  64. TEST_CASE("HandleListT", "")
  65. {
  66. bx::HandleListT<32> list;
  67. list.pushBack(16);
  68. REQUIRE(list.getFront() == 16);
  69. REQUIRE(list.getBack() == 16);
  70. list.pushFront(7);
  71. REQUIRE(list.getFront() == 7);
  72. REQUIRE(list.getBack() == 16);
  73. uint16_t expected0[] = { 15, 31, 7, 16, 17, 11, 13 };
  74. list.pushBack(17);
  75. list.pushBack(11);
  76. list.pushBack(13);
  77. list.pushFront(31);
  78. list.pushFront(15);
  79. uint16_t count = 0;
  80. for (uint16_t it = list.getFront(); it != UINT16_MAX; it = list.getNext(it), ++count)
  81. {
  82. REQUIRE(it == expected0[count]);
  83. }
  84. REQUIRE(count == BX_COUNTOF(expected0) );
  85. list.remove(17);
  86. list.remove(31);
  87. list.remove(16);
  88. list.pushBack(16);
  89. uint16_t expected1[] = { 15, 7, 11, 13, 16 };
  90. count = 0;
  91. for (uint16_t it = list.getFront(); it != UINT16_MAX; it = list.getNext(it), ++count)
  92. {
  93. REQUIRE(it == expected1[count]);
  94. }
  95. REQUIRE(count == BX_COUNTOF(expected1) );
  96. list.popBack();
  97. list.popFront();
  98. list.popBack();
  99. list.popBack();
  100. REQUIRE(list.getFront() == 7);
  101. REQUIRE(list.getBack() == 7);
  102. list.popBack();
  103. REQUIRE(list.getFront() == UINT16_MAX);
  104. REQUIRE(list.getBack() == UINT16_MAX);
  105. }
  106. TEST_CASE("HandleAllocLruT", "")
  107. {
  108. bx::HandleAllocLruT<16> lru;
  109. uint16_t handle[4] =
  110. {
  111. lru.alloc(),
  112. lru.alloc(),
  113. lru.alloc(),
  114. lru.alloc(),
  115. };
  116. lru.touch(handle[1]);
  117. uint16_t expected0[] = { handle[1], handle[3], handle[2], handle[0] };
  118. uint16_t count = 0;
  119. for (uint16_t it = lru.getFront(); it != UINT16_MAX; it = lru.getNext(it), ++count)
  120. {
  121. REQUIRE(it == expected0[count]);
  122. }
  123. }
  124. TEST_CASE("HandleHashTable", "")
  125. {
  126. typedef bx::HandleHashMapT<512> HashMap;
  127. HashMap hm;
  128. REQUIRE(512 == hm.getMaxCapacity() );
  129. bx::StringView sv0("test0");
  130. bool ok = hm.insert(bx::hash<bx::HashMurmur2A>(sv0), 0);
  131. REQUIRE(ok);
  132. ok = hm.insert(bx::hash<bx::HashMurmur2A>(sv0), 0);
  133. REQUIRE(!ok);
  134. REQUIRE(1 == hm.getNumElements() );
  135. bx::StringView sv1("test1");
  136. ok = hm.insert(bx::hash<bx::HashMurmur2A>(sv1), 0);
  137. REQUIRE(ok);
  138. REQUIRE(2 == hm.getNumElements() );
  139. hm.removeByHandle(0);
  140. REQUIRE(0 == hm.getNumElements() );
  141. ok = hm.insert(bx::hash<bx::HashMurmur2A>(sv0), 0);
  142. REQUIRE(ok);
  143. hm.removeByKey(bx::hash<bx::HashMurmur2A>(sv0) );
  144. REQUIRE(0 == hm.getNumElements() );
  145. for (uint32_t ii = 0, num = hm.getMaxCapacity(); ii < num; ++ii)
  146. {
  147. ok = hm.insert(ii, uint16_t(ii) );
  148. REQUIRE(ok);
  149. }
  150. }