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

Side by Side Diff: runtime/lib/collection_patch.dart

Issue 23883003: Revert "Add custom equals and hashCode for HashMap implementation." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 3 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 | « no previous file | sdk/lib/_internal/lib/collection_patch.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 patch class HashMap<K, V> { 5 patch class HashMap<K, V> {
6 /* patch */ factory HashMap({ bool equals(K key1, K key2),
7 int hashCode(K key) }) {
8 if (hashCode == null) {
9 if (equals == null) {
10 return new _HashMapImpl<K, V>();
11 }
12 if (identical(identical, equals)) {
13 return new _IdentityHashMap<K, V>();
14 }
15 hashCode = _defaultHashCode;
16 } else if (equals == null) {
17 equals = _defaultEquals;
18 }
19 return new _CustomHashMap<K, V>(equals, hashCode);
20 }
21 }
22
23 const int _MODIFICATION_COUNT_MASK = 0x3fffffff;
24
25 class _HashMapImpl<K, V> implements HashMap<K, V> {
26 static const int _INITIAL_CAPACITY = 8; 6 static const int _INITIAL_CAPACITY = 8;
7 static const int _MODIFICATION_COUNT_MASK = 0x3fffffff;
27 8
28 int _elementCount = 0; 9 int _elementCount = 0;
29 List<_HashMapEntry> _buckets = new List(_INITIAL_CAPACITY); 10 List<_HashMapEntry> _buckets = new List(_INITIAL_CAPACITY);
30 int _modificationCount = 0; 11 int _modificationCount = 0;
31 12
32 int get length => _elementCount; 13 /* patch */ HashMap._internal();
33 bool get isEmpty => _elementCount == 0;
34 bool get isNotEmpty => _elementCount != 0;
35 14
36 Iterable<K> get keys => new _HashMapKeyIterable<K>(this); 15 /* patch */ int get length => _elementCount;
37 Iterable<V> get values => new _HashMapValueIterable<V>(this); 16 /* patch */ bool get isEmpty => _elementCount == 0;
17 /* patch */ bool get isNotEmpty => _elementCount != 0;
38 18
39 bool containsKey(Object key) { 19 /* patch */ Iterable<K> get keys => new _HashMapKeyIterable<K>(this);
20 /* patch */ Iterable<V> get values => new _HashMapValueIterable<V>(this);
21
22 /* patch */ bool containsKey(Object key) {
40 int hashCode = key.hashCode; 23 int hashCode = key.hashCode;
41 List buckets = _buckets; 24 List buckets = _buckets;
42 int index = hashCode & (buckets.length - 1); 25 int index = hashCode & (buckets.length - 1);
43 _HashMapEntry entry = buckets[index]; 26 _HashMapEntry entry = buckets[index];
44 while (entry != null) { 27 while (entry != null) {
45 if (hashCode == entry.hashCode && entry.key == key) return true; 28 if (hashCode == entry.hashCode && entry.key == key) return true;
46 entry = entry.next; 29 entry = entry.next;
47 } 30 }
48 return false; 31 return false;
49 } 32 }
50 33
51 bool containsValue(Object value) { 34 /* patch */ bool containsValue(Object value) {
52 List buckets = _buckets; 35 List buckets = _buckets;
53 int length = buckets.length; 36 int length = buckets.length;
54 for (int i = 0; i < length; i++) { 37 for (int i = 0; i < length; i++) {
55 _HashMapEntry entry = buckets[i]; 38 _HashMapEntry entry = buckets[i];
56 while (entry != null) { 39 while (entry != null) {
57 if (entry.value == value) return true; 40 if (entry.value == value) return true;
58 entry = entry.next; 41 entry = entry.next;
59 } 42 }
60 } 43 }
61 return false; 44 return false;
62 } 45 }
63 46
64 V operator[](Object key) { 47 /* patch */ V operator[](Object key) {
65 int hashCode = key.hashCode; 48 int hashCode = key.hashCode;
66 List buckets = _buckets; 49 List buckets = _buckets;
67 int index = hashCode & (buckets.length - 1); 50 int index = hashCode & (buckets.length - 1);
68 _HashMapEntry entry = buckets[index]; 51 _HashMapEntry entry = buckets[index];
69 while (entry != null) { 52 while (entry != null) {
70 if (hashCode == entry.hashCode && entry.key == key) { 53 if (hashCode == entry.hashCode && entry.key == key) {
71 return entry.value; 54 return entry.value;
72 } 55 }
73 entry = entry.next; 56 entry = entry.next;
74 } 57 }
75 return null; 58 return null;
76 } 59 }
77 60
78 void operator []=(K key, V value) { 61 /* patch */ void operator []=(K key, V value) {
79 int hashCode = key.hashCode; 62 int hashCode = key.hashCode;
80 List buckets = _buckets; 63 List buckets = _buckets;
81 int length = buckets.length; 64 int length = buckets.length;
82 int index = hashCode & (length - 1); 65 int index = hashCode & (length - 1);
83 _HashMapEntry entry = buckets[index]; 66 _HashMapEntry entry = buckets[index];
84 while (entry != null) { 67 while (entry != null) {
85 if (hashCode == entry.hashCode && entry.key == key) { 68 if (hashCode == entry.hashCode && entry.key == key) {
86 entry.value = value; 69 entry.value = value;
87 return; 70 return;
88 } 71 }
89 entry = entry.next; 72 entry = entry.next;
90 } 73 }
91 _addEntry(buckets, index, length, key, value, hashCode); 74 _addEntry(buckets, index, length, key, value, hashCode);
92 } 75 }
93 76
94 V putIfAbsent(K key, V ifAbsent()) { 77 /* patch */ V putIfAbsent(K key, V ifAbsent()) {
95 int hashCode = key.hashCode; 78 int hashCode = key.hashCode;
96 List buckets = _buckets; 79 List buckets = _buckets;
97 int length = buckets.length; 80 int length = buckets.length;
98 int index = hashCode & (length - 1); 81 int index = hashCode & (length - 1);
99 _HashMapEntry entry = buckets[index]; 82 _HashMapEntry entry = buckets[index];
100 while (entry != null) { 83 while (entry != null) {
101 if (hashCode == entry.hashCode && entry.key == key) { 84 if (hashCode == entry.hashCode && entry.key == key) {
102 return entry.value; 85 return entry.value;
103 } 86 }
104 entry = entry.next; 87 entry = entry.next;
105 } 88 }
106 int stamp = _modificationCount; 89 int stamp = _modificationCount;
107 V value = ifAbsent(); 90 V value = ifAbsent();
108 if (stamp == _modificationCount) { 91 if (stamp == _modificationCount) {
109 _addEntry(buckets, index, length, key, value, hashCode); 92 _addEntry(buckets, index, length, key, value, hashCode);
110 } else { 93 } else {
111 this[key] = value; 94 this[key] = value;
112 } 95 }
113 return value; 96 return value;
114 } 97 }
115 98
116 void addAll(Map<K, V> other) { 99 /* patch */ void addAll(Map<K, V> other) {
117 other.forEach((K key, V value) { 100 other.forEach((K key, V value) {
118 this[key] = value; 101 this[key] = value;
119 }); 102 });
120 } 103 }
121 104
122 void forEach(void action(K key, V value)) { 105 /* patch */ void forEach(void action(K key, V value)) {
123 int stamp = _modificationCount; 106 int stamp = _modificationCount;
124 List buckets = _buckets; 107 List buckets = _buckets;
125 int length = buckets.length; 108 int length = buckets.length;
126 for (int i = 0; i < length; i++) { 109 for (int i = 0; i < length; i++) {
127 _HashMapEntry entry = buckets[i]; 110 _HashMapEntry entry = buckets[i];
128 while (entry != null) { 111 while (entry != null) {
129 action(entry.key, entry.value); 112 action(entry.key, entry.value);
130 if (stamp != _modificationCount) { 113 if (stamp != _modificationCount) {
131 throw new ConcurrentModificationError(this); 114 throw new ConcurrentModificationError(this);
132 } 115 }
133 entry = entry.next; 116 entry = entry.next;
134 } 117 }
135 } 118 }
136 } 119 }
137 120
138 V remove(Object key) { 121 /* patch */ V remove(Object key) {
139 int hashCode = key.hashCode; 122 int hashCode = key.hashCode;
140 List buckets = _buckets; 123 List buckets = _buckets;
141 int index = hashCode & (buckets.length - 1); 124 int index = hashCode & (buckets.length - 1);
142 _HashMapEntry entry = buckets[index]; 125 _HashMapEntry entry = buckets[index];
143 _HashMapEntry previous = null; 126 _HashMapEntry previous = null;
144 while (entry != null) { 127 while (entry != null) {
145 _HashMapEntry next = entry.next; 128 _HashMapEntry next = entry.next;
146 if (hashCode == entry.hashCode && entry.key == key) { 129 if (hashCode == entry.hashCode && entry.key == key) {
147 if (previous == null) { 130 if (previous == null) {
148 buckets[index] = next; 131 buckets[index] = next;
149 } else { 132 } else {
150 previous.next = next; 133 previous.next = next;
151 } 134 }
152 _elementCount--; 135 _elementCount--;
153 _modificationCount = 136 _modificationCount =
154 (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; 137 (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
155 return entry.value; 138 return entry.value;
156 } 139 }
157 previous = entry; 140 previous = entry;
158 entry = next; 141 entry = next;
159 } 142 }
160 return null; 143 return null;
161 } 144 }
162 145
163 void clear() { 146 /* patch */ void clear() {
164 _elementCount = 0; 147 _elementCount = 0;
165 _buckets = new List(_INITIAL_CAPACITY); 148 _buckets = new List(_INITIAL_CAPACITY);
166 _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; 149 _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
167 } 150 }
168 151
169 void _addEntry(List buckets, int index, int length, 152 void _addEntry(List buckets, int index, int length,
170 K key, V value, int hashCode) { 153 K key, V value, int hashCode) {
171 _HashMapEntry entry = 154 _HashMapEntry entry =
172 new _HashMapEntry(key, value, hashCode, buckets[index]); 155 new _HashMapEntry(key, value, hashCode, buckets[index]);
173 buckets[index] = entry; 156 buckets[index] = entry;
(...skipping 18 matching lines...) Expand all
192 int index = hashCode & (newLength - 1); 175 int index = hashCode & (newLength - 1);
193 entry.next = newBuckets[index]; 176 entry.next = newBuckets[index];
194 newBuckets[index] = entry; 177 newBuckets[index] = entry;
195 entry = next; 178 entry = next;
196 } 179 }
197 } 180 }
198 _buckets = newBuckets; 181 _buckets = newBuckets;
199 } 182 }
200 } 183 }
201 184
202 class _CustomHashMap<K, V> extends _HashMapImpl<K, V> {
203 final Function _equals;
204 final Function _hashCode;
205 _CustomHashMap(this._equals, this._hashCode);
206
207 bool containsKey(Object key) {
208 int hashCode = _hashCode(key);
209 List buckets = _buckets;
210 int index = hashCode & (buckets.length - 1);
211 _HashMapEntry entry = buckets[index];
212 while (entry != null) {
213 if (hashCode == entry.hashCode && _equals(entry.key, key)) return true;
214 entry = entry.next;
215 }
216 return false;
217 }
218
219 V operator[](Object key) {
220 int hashCode = _hashCode(key);
221 List buckets = _buckets;
222 int index = hashCode & (buckets.length - 1);
223 _HashMapEntry entry = buckets[index];
224 while (entry != null) {
225 if (hashCode == entry.hashCode && _equals(entry.key, key)) {
226 return entry.value;
227 }
228 entry = entry.next;
229 }
230 return null;
231 }
232
233 void operator []=(K key, V value) {
234 int hashCode = _hashCode(key);
235 List buckets = _buckets;
236 int length = buckets.length;
237 int index = hashCode & (length - 1);
238 _HashMapEntry entry = buckets[index];
239 while (entry != null) {
240 if (hashCode == entry.hashCode && _equals(entry.key, key)) {
241 entry.value = value;
242 return;
243 }
244 entry = entry.next;
245 }
246 _addEntry(buckets, index, length, key, value, hashCode);
247 }
248
249 V putIfAbsent(K key, V ifAbsent()) {
250 int hashCode = _hashCode(key);
251 List buckets = _buckets;
252 int length = buckets.length;
253 int index = hashCode & (length - 1);
254 _HashMapEntry entry = buckets[index];
255 while (entry != null) {
256 if (hashCode == entry.hashCode && _equals(entry.key, key)) {
257 return entry.value;
258 }
259 entry = entry.next;
260 }
261 int stamp = _modificationCount;
262 V value = ifAbsent();
263 if (stamp == _modificationCount) {
264 _addEntry(buckets, index, length, key, value, hashCode);
265 } else {
266 this[key] = value;
267 }
268 return value;
269 }
270
271 V remove(Object key) {
272 int hashCode = _hashCode(key);
273 List buckets = _buckets;
274 int index = hashCode & (buckets.length - 1);
275 _HashMapEntry entry = buckets[index];
276 _HashMapEntry previous = null;
277 while (entry != null) {
278 _HashMapEntry next = entry.next;
279 if (hashCode == entry.hashCode && _equals(entry.key, key)) {
280 if (previous == null) {
281 buckets[index] = next;
282 } else {
283 previous.next = next;
284 }
285 _elementCount--;
286 _modificationCount =
287 (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
288 return entry.value;
289 }
290 previous = entry;
291 entry = next;
292 }
293 return null;
294 }
295 }
296
297 class _IdentityHashMap<K, V> extends _HashMapImpl<K, V> {
298 bool containsKey(Object key) {
299 int hashCode = key.hashCode;
300 List buckets = _buckets;
301 int index = hashCode & (buckets.length - 1);
302 _HashMapEntry entry = buckets[index];
303 while (entry != null) {
304 if (hashCode == entry.hashCode && identical(entry.key, key)) return true;
305 entry = entry.next;
306 }
307 return false;
308 }
309
310 V operator[](Object key) {
311 int hashCode = key.hashCode;
312 List buckets = _buckets;
313 int index = hashCode & (buckets.length - 1);
314 _HashMapEntry entry = buckets[index];
315 while (entry != null) {
316 if (hashCode == entry.hashCode && identical(entry.key, key)) {
317 return entry.value;
318 }
319 entry = entry.next;
320 }
321 return null;
322 }
323
324 void operator []=(K key, V value) {
325 int hashCode = key.hashCode;
326 List buckets = _buckets;
327 int length = buckets.length;
328 int index = hashCode & (length - 1);
329 _HashMapEntry entry = buckets[index];
330 while (entry != null) {
331 if (hashCode == entry.hashCode && identical(entry.key, key)) {
332 entry.value = value;
333 return;
334 }
335 entry = entry.next;
336 }
337 _addEntry(buckets, index, length, key, value, hashCode);
338 }
339
340 V putIfAbsent(K key, V ifAbsent()) {
341 int hashCode = key.hashCode;
342 List buckets = _buckets;
343 int length = buckets.length;
344 int index = hashCode & (length - 1);
345 _HashMapEntry entry = buckets[index];
346 while (entry != null) {
347 if (hashCode == entry.hashCode && identical(entry.key, key)) {
348 return entry.value;
349 }
350 entry = entry.next;
351 }
352 int stamp = _modificationCount;
353 V value = ifAbsent();
354 if (stamp == _modificationCount) {
355 _addEntry(buckets, index, length, key, value, hashCode);
356 } else {
357 this[key] = value;
358 }
359 return value;
360 }
361
362 V remove(Object key) {
363 int hashCode = key.hashCode;
364 List buckets = _buckets;
365 int index = hashCode & (buckets.length - 1);
366 _HashMapEntry entry = buckets[index];
367 _HashMapEntry previous = null;
368 while (entry != null) {
369 _HashMapEntry next = entry.next;
370 if (hashCode == entry.hashCode && identical(entry.key, key)) {
371 if (previous == null) {
372 buckets[index] = next;
373 } else {
374 previous.next = next;
375 }
376 _elementCount--;
377 _modificationCount =
378 (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
379 return entry.value;
380 }
381 previous = entry;
382 entry = next;
383 }
384 return null;
385 }
386 }
387
388
389 class _HashMapEntry { 185 class _HashMapEntry {
390 final key; 186 final key;
391 var value; 187 var value;
392 final int hashCode; 188 final int hashCode;
393 _HashMapEntry next; 189 _HashMapEntry next;
394 _HashMapEntry(this.key, this.value, this.hashCode, this.next); 190 _HashMapEntry(this.key, this.value, this.hashCode, this.next);
395 } 191 }
396 192
397 abstract class _HashMapIterable<E> extends IterableBase<E> { 193 abstract class _HashMapIterable<E> extends IterableBase<E> {
398 final HashMap _map; 194 final HashMap _map;
(...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 1307
1512 _LinkedHashMapTable() : super(_INITIAL_CAPACITY); 1308 _LinkedHashMapTable() : super(_INITIAL_CAPACITY);
1513 1309
1514 V _value(int offset) => _table[offset + _VALUE_INDEX]; 1310 V _value(int offset) => _table[offset + _VALUE_INDEX];
1515 void _setValue(int offset, V value) { _table[offset + _VALUE_INDEX] = value; } 1311 void _setValue(int offset, V value) { _table[offset + _VALUE_INDEX] = value; }
1516 1312
1517 _copyEntry(List oldTable, int fromOffset, int toOffset) { 1313 _copyEntry(List oldTable, int fromOffset, int toOffset) {
1518 _table[toOffset + _VALUE_INDEX] = oldTable[fromOffset + _VALUE_INDEX]; 1314 _table[toOffset + _VALUE_INDEX] = oldTable[fromOffset + _VALUE_INDEX];
1519 } 1315 }
1520 } 1316 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/lib/collection_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698