Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(537)

Side by Side Diff: tests/corelib/hash_map2_test.dart

Issue 12212211: Reapply "New implementation of {,Linked}Hash{Set,Map}." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix breaks in pub. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tests/co19/co19-runtime.status ('k') | tests/corelib/hash_set_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013, 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 // Tests of hash map behavior, with focus in iteration and concurrent
6 // modification errors.
7
8 library hash_map2_test;
9 import 'dart:collection';
10
11 testMap(Map newMap(), Map newMapFrom(Map map)) {
12 Map gen(int from, int to) {
13 Map map = new LinkedHashMap();
14 for (int i = from; i < to; i++) map[i] = i;
15 return map;
16 }
17
18 bool odd(int n) => (n & 1) == 1;
19 bool even(int n) => (n & 1) == 0;
20 void addAll(Map toMap, Map fromMap) {
21 fromMap.forEach((k, v) { toMap[k] = v; });
22 }
23
24 { // Test growing to largish capacity.
25 Map map = newMap();
26
27 for (int i = 0; i < 256; i++) {
28 map[i] = i;
29 }
30 addAll(map, gen(256, 512));
31 addAll(map, newMapFrom(gen(512, 1000)));
32 Expect.equals(1000, map.length);
33
34 // Remove half.
35 for (int i = 0; i < 1000; i += 2) map.remove(i);
36 Expect.equals(500, map.length);
37 Expect.isFalse(map.keys.any(even));
38 Expect.isTrue(map.keys.every(odd));
39
40 // Re-add all.
41 addAll(map, gen(0, 1000));
42 Expect.equals(1000, map.length);
43 }
44
45 { // Test having many deleted elements.
46 Map map = newMap();
47 map[0] = 0;
48 for (int i = 0; i < 1000; i++) {
49 map[i + 1] = i + 1;
50 map.remove(i);
51 Expect.equals(1, map.length);
52 }
53 }
54
55 { // Test having many elements with same hashCode
56 Map map = newMap();
57 for (int i = 0; i < 1000; i++) {
58 map[new BadHashCode()] = 0;
59 }
60 Expect.equals(1000, map.length);
61 }
62
63 { // Check concurrent modification
64 Map map = newMap()..[0] = 0..[1] = 1;
65
66 { // Test adding before a moveNext.
67 Iterator iter = map.keys.iterator;
68 iter.moveNext();
69 map[1] = 9; // Updating existing key isn't a modification.
70 iter.moveNext();
71 map[2] = 2;
72 Expect.throws(iter.moveNext, (e) => e is Error);
73 }
74
75 { // Test adding after last element.
76 Iterator iter = map.keys.iterator;
77 Expect.equals(3, map.length);
78 iter.moveNext();
79 iter.moveNext();
80 iter.moveNext();
81 map[3] = 3;
82 Expect.throws(iter.moveNext, (e) => e is Error);
83 }
84
85 { // Test removing during iteration.
86 Iterator iter = map.keys.iterator;
87 iter.moveNext();
88 map.remove(1000); // Not a modification if it's not there.
89 iter.moveNext();
90 int n = iter.current;
91 map.remove(n);
92 // Removing doesn't change current.
93 Expect.equals(n, iter.current);
94 Expect.throws(iter.moveNext, (e) => e is Error);
95 }
96
97 { // Test removing after last element.
98 Iterator iter = map.keys.iterator;
99 Expect.equals(3, map.length);
100 iter.moveNext();
101 iter.moveNext();
102 iter.moveNext();
103 int n = iter.current;
104 map.remove(n);
105 // Removing doesn't change current.
106 Expect.equals(n, iter.current);
107 Expect.throws(iter.moveNext, (e) => e is Error);
108 }
109
110 { // Test that updating value of existing key doesn't cause concurrent
111 // modification error.
112 Iterator iter = map.keys.iterator;
113 Expect.equals(2, map.length);
114 iter.moveNext();
115 int n = iter.current;
116 map[n] = n * 2;
117 iter.moveNext();
118 Expect.equals(map[iter.current], iter.current);
119 }
120
121 { // Test that modification during putIfAbsent is not an error.
122 map.putIfAbsent(4, () {
123 map[5] = 5;
124 map[4] = -1;
125 return 4;
126 });
127 Expect.equals(4, map[4]);
128 Expect.equals(5, map[5]);
129 }
130
131 { // Check adding many existing keys isn't considered modification.
132 Map map2 = newMap();
133 for (var key in map.keys) {
134 map2[key] = map[key] + 1;
135 }
136 Iterator iter = map.keys.iterator;
137 addAll(map, map2);
138 // Shouldn't throw.
139 iter.moveNext();
140 }
141 }
142
143 { // Regression test for bug in putIfAbsent where adding an element
144 // that make the table grow, can be lost.
145 Map map = newMap();
146 map.putIfAbsent("S", () => 0);
147 map.putIfAbsent("T", () => 0);
148 map.putIfAbsent("U", () => 0);
149 map.putIfAbsent("C", () => 0);
150 map.putIfAbsent("a", () => 0);
151 map.putIfAbsent("b", () => 0);
152 map.putIfAbsent("n", () => 0);
153 Expect.isTrue(map.containsKey("n"));
154 }
155
156 { // Check that putIfAbsent works just as well as put.
157 Map map = newMap();
158 for (int i = 0; i < 128; i++) {
159 map.putIfAbsent(i, () => i);
160 Expect.isTrue(map.containsKey(i));
161 map.putIfAbsent(i >> 1, () => -1); // Never triggers.
162 }
163 for (int i = 0; i < 128; i++) {
164 Expect.equals(i, map[i]);
165 }
166 }
167
168 { // Check that updating existing elements is not a modification.
169 // This must be the case even if the underlying data structure is
170 // nearly full.
171 for (int i = 1; i < 128; i++) {
172 // Create maps of different sizes, some of which should be
173 // at a limit of the underlying data structure.
174 Map map = newMapFrom(gen(0, i));
175
176 // ForEach-iteration.
177 map.forEach((key, v) {
178 Expect.equals(key, map[key]);
179 map[key] = key + 1;
180 map.remove(1000); // Removing something not there.
181 map.putIfAbsent(key, () => Expect.fail("SHOULD NOT BE ABSENT"));
182 // Doesn't cause ConcurrentModificationError.
183 });
184
185 // for-in iteration.
186 for (int key in map.keys) {
187 Expect.equals(key + 1, map[key]);
188 map[key] = map[key] + 1;
189 map.remove(1000); // Removing something not there.
190 map.putIfAbsent(key, () => Expect.fail("SHOULD NOT BE ABSENT"));
191 // Doesn't cause ConcurrentModificationError.
192 }
193
194 // Raw iterator.
195 Iterator iter = map.keys.iterator;
196 for (int key = 0; key < i; key++) {
197 Expect.equals(key + 2, map[key]);
198 map[key] = key + 3;
199 map.remove(1000); // Removing something not there.
200 map.putIfAbsent(key, () => Expect.fail("SHOULD NOT BE ABSENT"));
201 // Doesn't cause ConcurrentModificationError on the moveNext.
202 }
203 iter.moveNext(); // Should not throw.
204
205 // Remove a lot of elements, which can cause a re-tabulation.
206 for (int key = 1; key < i; key++) {
207 Expect.equals(key + 3, map[key]);
208 map.remove(key);
209 }
210 iter = map.keys.iterator;
211 map[0] = 2;
212 iter.moveNext(); // Should not throw.
213 }
214 }
215
216
217 { // Check that null can be in the map.
218 Map map = newMap();
219 map[null] = 0;
220 Expect.equals(1, map.length);
221 Expect.isTrue(map.containsKey(null));
222 Expect.isNull(map.keys.first);
223 Expect.isNull(map.keys.last);
224 map[null] = 1;
225 Expect.equals(1, map.length);
226 Expect.isTrue(map.containsKey(null));
227 map.remove(null);
228 Expect.isTrue(map.isEmpty);
229 Expect.isFalse(map.containsKey(null));
230
231 // Created using map.from.
232 map = newMapFrom(new Map()..[null] = 0);
233 Expect.equals(1, map.length);
234 Expect.isTrue(map.containsKey(null));
235 Expect.isNull(map.keys.first);
236 Expect.isNull(map.keys.last);
237 map[null] = 1;
238 Expect.equals(1, map.length);
239 Expect.isTrue(map.containsKey(null));
240 map.remove(null);
241 Expect.isTrue(map.isEmpty);
242 Expect.isFalse(map.containsKey(null));
243
244 Map fromMap = new Map();
245 fromMap[1] = 0;
246 fromMap[2] = 0;
247 fromMap[3] = 0;
248 fromMap[null] = 0;
249 fromMap[4] = 0;
250 fromMap[5] = 0;
251 fromMap[6] = 0;
252 Expect.equals(7, fromMap.length);
253
254 // map that grows with null in it.
255 map = newMapFrom(fromMap);
256 Expect.equals(7, map.length);
257 for (int i = 7; i < 128; i++) {
258 map[i] = 0;
259 }
260 Expect.equals(128, map.length);
261 Expect.isTrue(map.containsKey(null));
262 map[null] = 1;
263 Expect.equals(128, map.length);
264 Expect.isTrue(map.containsKey(null));
265 map.remove(null);
266 Expect.equals(127, map.length);
267 Expect.isFalse(map.containsKey(null));
268 }
269 }
270
271 void main() {
272 Expect.isTrue(new HashMap<int, String>() is Map<int, String>);
273 Expect.isTrue(new LinkedHashMap<int, String>() is Map<int, String>);
274 Expect.isTrue(new HashMap<String, int>.from({}) is Map<String, int>);
275 Expect.isTrue(new LinkedHashMap<String, int>.from({}) is Map<String, int>);
276 Expect.isTrue(<String, int>{} is Map<String, int>);
277 Expect.isTrue(const <String, int>{} is Map<String, int>);
278
279 testMap(() => new HashMap(), (m) => new HashMap.from(m));
280 testMap(() => new LinkedHashMap(), (m) => new LinkedHashMap.from(m));
281 }
282
283
284 class BadHashCode {
285 static int idCounter = 0;
286 final int id;
287 BadHashCode() : id = idCounter++;
288 int get hashCode => 42;
289 }
OLDNEW
« no previous file with comments | « tests/co19/co19-runtime.status ('k') | tests/corelib/hash_set_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698