addressmap_unittest.cc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
  2. // Copyright (c) 2005, Google Inc.
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. // ---
  31. // Author: Sanjay Ghemawat
  32. #include <stdlib.h> // for rand()
  33. #include <vector>
  34. #include <set>
  35. #include <algorithm>
  36. #include <utility>
  37. #include "addressmap-inl.h"
  38. #include "base/logging.h"
  39. #include "base/commandlineflags.h"
  40. DEFINE_int32(iters, 20, "Number of test iterations");
  41. DEFINE_int32(N, 100000, "Number of elements to test per iteration");
  42. using std::pair;
  43. using std::make_pair;
  44. using std::vector;
  45. using std::set;
  46. using std::random_shuffle;
  47. struct UniformRandomNumberGenerator {
  48. size_t Uniform(size_t max_size) {
  49. if (max_size == 0)
  50. return 0;
  51. return rand() % max_size; // not a great random-number fn, but portable
  52. }
  53. };
  54. static UniformRandomNumberGenerator rnd;
  55. // pair of associated value and object size
  56. typedef pair<int, size_t> ValueT;
  57. struct PtrAndSize {
  58. char* ptr;
  59. size_t size;
  60. PtrAndSize(char* p, size_t s) : ptr(p), size(s) {}
  61. };
  62. size_t SizeFunc(const ValueT& v) { return v.second; }
  63. static void SetCheckCallback(const void* ptr, ValueT* val,
  64. set<pair<const void*, int> >* check_set) {
  65. check_set->insert(make_pair(ptr, val->first));
  66. }
  67. int main(int argc, char** argv) {
  68. // Get a bunch of pointers
  69. const int N = FLAGS_N;
  70. static const int kMaxRealSize = 49;
  71. // 100Mb to stress not finding previous object (AddressMap's cluster is 1Mb):
  72. static const size_t kMaxSize = 100*1000*1000;
  73. vector<PtrAndSize> ptrs_and_sizes;
  74. for (int i = 0; i < N; ++i) {
  75. size_t s = rnd.Uniform(kMaxRealSize);
  76. ptrs_and_sizes.push_back(PtrAndSize(new char[s], s));
  77. }
  78. for (int x = 0; x < FLAGS_iters; ++x) {
  79. RAW_LOG(INFO, "Iteration %d/%d...\n", x, FLAGS_iters);
  80. // Permute pointers to get rid of allocation order issues
  81. random_shuffle(ptrs_and_sizes.begin(), ptrs_and_sizes.end());
  82. AddressMap<ValueT> map(malloc, free);
  83. const ValueT* result;
  84. const void* res_p;
  85. // Insert a bunch of entries
  86. for (int i = 0; i < N; ++i) {
  87. char* p = ptrs_and_sizes[i].ptr;
  88. CHECK(!map.Find(p));
  89. int offs = rnd.Uniform(ptrs_and_sizes[i].size);
  90. CHECK(!map.FindInside(&SizeFunc, kMaxSize, p + offs, &res_p));
  91. map.Insert(p, make_pair(i, ptrs_and_sizes[i].size));
  92. CHECK(result = map.Find(p));
  93. CHECK_EQ(result->first, i);
  94. CHECK(result = map.FindInside(&SizeFunc, kMaxRealSize, p + offs, &res_p));
  95. CHECK_EQ(res_p, p);
  96. CHECK_EQ(result->first, i);
  97. map.Insert(p, make_pair(i + N, ptrs_and_sizes[i].size));
  98. CHECK(result = map.Find(p));
  99. CHECK_EQ(result->first, i + N);
  100. }
  101. // Delete the even entries
  102. for (int i = 0; i < N; i += 2) {
  103. void* p = ptrs_and_sizes[i].ptr;
  104. ValueT removed;
  105. CHECK(map.FindAndRemove(p, &removed));
  106. CHECK_EQ(removed.first, i + N);
  107. }
  108. // Lookup the odd entries and adjust them
  109. for (int i = 1; i < N; i += 2) {
  110. char* p = ptrs_and_sizes[i].ptr;
  111. CHECK(result = map.Find(p));
  112. CHECK_EQ(result->first, i + N);
  113. int offs = rnd.Uniform(ptrs_and_sizes[i].size);
  114. CHECK(result = map.FindInside(&SizeFunc, kMaxRealSize, p + offs, &res_p));
  115. CHECK_EQ(res_p, p);
  116. CHECK_EQ(result->first, i + N);
  117. map.Insert(p, make_pair(i + 2*N, ptrs_and_sizes[i].size));
  118. CHECK(result = map.Find(p));
  119. CHECK_EQ(result->first, i + 2*N);
  120. }
  121. // Insert even entries back
  122. for (int i = 0; i < N; i += 2) {
  123. char* p = ptrs_and_sizes[i].ptr;
  124. int offs = rnd.Uniform(ptrs_and_sizes[i].size);
  125. CHECK(!map.FindInside(&SizeFunc, kMaxSize, p + offs, &res_p));
  126. map.Insert(p, make_pair(i + 2*N, ptrs_and_sizes[i].size));
  127. CHECK(result = map.Find(p));
  128. CHECK_EQ(result->first, i + 2*N);
  129. CHECK(result = map.FindInside(&SizeFunc, kMaxRealSize, p + offs, &res_p));
  130. CHECK_EQ(res_p, p);
  131. CHECK_EQ(result->first, i + 2*N);
  132. }
  133. // Check all entries
  134. set<pair<const void*, int> > check_set;
  135. map.Iterate(SetCheckCallback, &check_set);
  136. CHECK_EQ(check_set.size(), N);
  137. for (int i = 0; i < N; ++i) {
  138. void* p = ptrs_and_sizes[i].ptr;
  139. check_set.erase(make_pair(p, i + 2*N));
  140. CHECK(result = map.Find(p));
  141. CHECK_EQ(result->first, i + 2*N);
  142. }
  143. CHECK_EQ(check_set.size(), 0);
  144. }
  145. for (int i = 0; i < N; ++i) {
  146. delete[] ptrs_and_sizes[i].ptr;
  147. }
  148. printf("PASS\n");
  149. return 0;
  150. }