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