OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 #include "bin/hashmap.h" | |
6 #include "platform/assert.h" | |
7 #include "platform/globals.h" | |
8 #include "vm/unit_test.h" | |
9 | |
10 static bool DefaultMatchFun(void* a, void* b) { | |
11 return a == b; | |
12 } | |
13 | |
14 | |
15 typedef uint32_t (*IntKeyHash)(uint32_t key); | |
16 | |
17 | |
18 class IntSet { | |
19 public: | |
20 explicit IntSet(IntKeyHash hash) : hash_(hash), map_(DefaultMatchFun) {} | |
21 | |
22 void Insert(int x) { | |
23 EXPECT_NE(0, x); // 0 corresponds to (void*)NULL - illegal key value | |
24 HashMap::Entry* p = map_.Lookup(reinterpret_cast<void*>(x), hash_(x), true); | |
25 EXPECT(p != NULL); // insert is set! | |
26 EXPECT_EQ(reinterpret_cast<void*>(x), p->key); | |
27 // We don't care about p->value. | |
28 } | |
29 | |
30 void Remove(int x) { | |
31 EXPECT_NE(0, x); // 0 corresponds to (void*)NULL - illegal key value | |
32 map_.Remove(reinterpret_cast<void*>(x), hash_(x)); | |
33 } | |
34 | |
35 bool Present(int x) { | |
36 HashMap::Entry* p = | |
37 map_.Lookup(reinterpret_cast<void*>(x), hash_(x), false); | |
38 if (p != NULL) { | |
39 EXPECT_EQ(reinterpret_cast<void*>(x), p->key); | |
40 } | |
41 return p != NULL; | |
42 } | |
43 | |
44 void Clear() { | |
45 map_.Clear(); | |
46 } | |
47 | |
48 uint32_t occupancy() const { | |
49 uint32_t count = 0; | |
50 for (HashMap::Entry* p = map_.Start(); p != NULL; p = map_.Next(p)) { | |
51 count++; | |
52 } | |
53 EXPECT_EQ(map_.occupancy(), static_cast<double>(count)); | |
Ivan Posva
2012/01/17 07:57:41
Why the cast to double?
Søren Gjesse
2012/01/17 09:28:04
Don't know. Changed count to type intptr_t and rem
| |
54 return count; | |
55 } | |
56 | |
57 private: | |
58 IntKeyHash hash_; | |
59 HashMap map_; | |
60 }; | |
61 | |
62 | |
63 static uint32_t Hash(uint32_t key) { return 23; } | |
64 static uint32_t CollisionHash(uint32_t key) { return key & 0x3; } | |
Ivan Posva
2012/01/17 07:57:41
By using these two hash functions you will tend to
Søren Gjesse
2012/01/17 09:28:04
Added a number of additional hash functions with c
| |
65 | |
66 | |
67 void TestSet(IntKeyHash hash, int size) { | |
68 IntSet set(hash); | |
69 EXPECT_EQ(0u, set.occupancy()); | |
70 | |
71 set.Insert(1); | |
72 set.Insert(2); | |
73 set.Insert(3); | |
74 EXPECT_EQ(3u, set.occupancy()); | |
75 | |
76 set.Insert(2); | |
77 set.Insert(3); | |
78 EXPECT_EQ(3u, set.occupancy()); | |
79 | |
80 EXPECT(set.Present(1)); | |
81 EXPECT(set.Present(2)); | |
82 EXPECT(set.Present(3)); | |
83 EXPECT(!set.Present(4)); | |
84 EXPECT_EQ(3u, set.occupancy()); | |
85 | |
86 set.Remove(1); | |
87 EXPECT(!set.Present(1)); | |
88 EXPECT(set.Present(2)); | |
89 EXPECT(set.Present(3)); | |
90 EXPECT_EQ(2u, set.occupancy()); | |
91 | |
92 set.Remove(3); | |
93 EXPECT(!set.Present(1)); | |
94 EXPECT(set.Present(2)); | |
95 EXPECT(!set.Present(3)); | |
96 EXPECT_EQ(1u, set.occupancy()); | |
97 | |
98 set.Clear(); | |
99 EXPECT_EQ(0u, set.occupancy()); | |
100 | |
101 // Insert a long series of values. | |
102 const int start = 453; | |
103 const int factor = 13; | |
104 const int offset = 7; | |
105 const uint32_t n = size; | |
106 | |
107 int x = start; | |
108 for (uint32_t i = 0; i < n; i++) { | |
109 EXPECT_EQ(i, static_cast<double>(set.occupancy())); | |
Ivan Posva
2012/01/17 07:57:41
ditto. Cast to double?
Søren Gjesse
2012/01/17 09:28:04
Removed.
| |
110 set.Insert(x); | |
111 x = x * factor + offset; | |
112 } | |
113 EXPECT_EQ(n, static_cast<double>(set.occupancy())); | |
Ivan Posva
2012/01/17 07:57:41
ditto. And more places...
Søren Gjesse
2012/01/17 09:28:04
Removed.
| |
114 | |
115 // Verify the same sequence of values. | |
116 x = start; | |
117 for (uint32_t i = 0; i < n; i++) { | |
118 EXPECT(set.Present(x)); | |
119 x = x * factor + offset; | |
120 } | |
121 EXPECT_EQ(n, static_cast<double>(set.occupancy())); | |
122 | |
123 // Remove all these values. | |
124 x = start; | |
125 for (uint32_t i = 0; i < n; i++) { | |
126 EXPECT_EQ(n - i, static_cast<double>(set.occupancy())); | |
127 EXPECT(set.Present(x)); | |
128 set.Remove(x); | |
129 EXPECT(!set.Present(x)); | |
130 x = x * factor + offset; | |
131 | |
132 // Verify the the expected values are still there. | |
133 int y = start; | |
134 for (uint32_t j = 0; j < n; j++) { | |
135 if (j <= i) { | |
136 EXPECT(!set.Present(y)); | |
137 } else { | |
138 EXPECT(set.Present(y)); | |
139 } | |
140 y = y * factor + offset; | |
141 } | |
142 } | |
143 EXPECT_EQ(0u, set.occupancy()); | |
144 } | |
145 | |
146 | |
147 UNIT_TEST_CASE(Set) { | |
148 TestSet(Hash, 100); | |
149 TestSet(CollisionHash, 50); | |
150 } | |
OLD | NEW |