crn_hash_map.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // File: crn_hash_map.cpp
  2. // See Copyright Notice and license at the end of inc/crnlib.h
  3. #include "crn_core.h"
  4. #include "crn_hash_map.h"
  5. #include "crn_rand.h"
  6. namespace crnlib
  7. {
  8. #if 0
  9. class counted_obj
  10. {
  11. public:
  12. counted_obj(uint v = 0) :
  13. m_val(v)
  14. {
  15. m_count++;
  16. }
  17. counted_obj(const counted_obj& obj) :
  18. m_val(obj.m_val)
  19. {
  20. m_count++;
  21. }
  22. ~counted_obj()
  23. {
  24. CRNLIB_ASSERT(m_count > 0);
  25. m_count--;
  26. }
  27. static uint m_count;
  28. uint m_val;
  29. operator size_t() const { return m_val; }
  30. bool operator== (const counted_obj& rhs) const { return m_val == rhs.m_val; }
  31. bool operator== (const uint rhs) const { return m_val == rhs; }
  32. };
  33. uint counted_obj::m_count;
  34. void hash_map_test()
  35. {
  36. random r0, r1;
  37. uint seed = 0;
  38. for ( ; ; )
  39. {
  40. seed++;
  41. typedef crnlib::hash_map<counted_obj, counted_obj> my_hash_map;
  42. my_hash_map m;
  43. const uint n = r0.irand(1, 100000);
  44. printf("%u\n", n);
  45. r1.seed(seed);
  46. crnlib::vector<int> q;
  47. uint count = 0;
  48. for (uint i = 0; i < n; i++)
  49. {
  50. uint v = r1.urand32() & 0x7FFFFFFF;
  51. my_hash_map::insert_result res = m.insert(counted_obj(v), counted_obj(v ^ 0xdeadbeef));
  52. if (res.second)
  53. {
  54. count++;
  55. q.push_back(v);
  56. }
  57. }
  58. CRNLIB_VERIFY(m.size() == count);
  59. r1.seed(seed);
  60. my_hash_map cm(m);
  61. m.clear();
  62. m = cm;
  63. cm.reset();
  64. for (uint i = 0; i < n; i++)
  65. {
  66. uint v = r1.urand32() & 0x7FFFFFFF;
  67. my_hash_map::const_iterator it = m.find(counted_obj(v));
  68. CRNLIB_VERIFY(it != m.end());
  69. CRNLIB_VERIFY(it->first == v);
  70. CRNLIB_VERIFY(it->second == (v ^ 0xdeadbeef));
  71. }
  72. for (uint t = 0; t < 2; t++)
  73. {
  74. const uint nd = r0.irand(1, q.size() + 1);
  75. for (uint i = 0; i < nd; i++)
  76. {
  77. uint p = r0.irand(0, q.size());
  78. int k = q[p];
  79. if (k >= 0)
  80. {
  81. q[p] = -k - 1;
  82. bool s = m.erase(counted_obj(k));
  83. CRNLIB_VERIFY(s);
  84. }
  85. }
  86. typedef crnlib::hash_map<uint, empty_type> uint_hash_set;
  87. uint_hash_set s;
  88. for (uint i = 0; i < q.size(); i++)
  89. {
  90. int v = q[i];
  91. if (v >= 0)
  92. {
  93. my_hash_map::const_iterator it = m.find(counted_obj(v));
  94. CRNLIB_VERIFY(it != m.end());
  95. CRNLIB_VERIFY(it->first == (uint)v);
  96. CRNLIB_VERIFY(it->second == ((uint)v ^ 0xdeadbeef));
  97. s.insert(v);
  98. }
  99. else
  100. {
  101. my_hash_map::const_iterator it = m.find(counted_obj(-v - 1));
  102. CRNLIB_VERIFY(it == m.end());
  103. }
  104. }
  105. uint found_count = 0;
  106. for (my_hash_map::const_iterator it = m.begin(); it != m.end(); ++it)
  107. {
  108. CRNLIB_VERIFY(it->second == ((uint)it->first ^ 0xdeadbeef));
  109. uint_hash_set::const_iterator fit(s.find((uint)it->first));
  110. CRNLIB_VERIFY(fit != s.end());
  111. CRNLIB_VERIFY(fit->first == it->first);
  112. found_count++;
  113. }
  114. CRNLIB_VERIFY(found_count == s.size());
  115. }
  116. CRNLIB_VERIFY(counted_obj::m_count == m.size() * 2);
  117. }
  118. }
  119. #endif
  120. } // namespace crnlib