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

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

Issue 23890008: Revert "Make LinkedHashMap also have a factory constructor and be customizable" (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
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), 6 /* patch */ factory HashMap({ bool equals(K key1, K key2),
7 int hashCode(K key), 7 int hashCode(K key) }) {
8 bool isValidKey(potentialKey) }) { 8 if (hashCode == null) {
9 if (isValidKey == null) { 9 if (equals == null) {
10 if (hashCode == null) { 10 return new _HashMapImpl<K, V>();
11 if (equals == null) {
12 return new _HashMap<K, V>();
13 }
14 if (identical(identical, equals)) {
15 return new _IdentityHashMap<K, V>();
16 }
17 hashCode = _defaultHashCode;
18 } else if (equals == null) {
19 equals = _defaultEquals;
20 } 11 }
21 } else { 12 if (identical(identical, equals)) {
22 if (hashCode == null) { 13 return new _IdentityHashMap<K, V>();
23 hashCode = _defaultHashCode;
24 } 14 }
25 if (equals == null) { 15 hashCode = _defaultHashCode;
26 equals = _defaultEquals; 16 } else if (equals == null) {
27 } 17 equals = _defaultEquals;
28 } 18 }
29 return new _CustomHashMap<K, V>(equals, hashCode, isValidKey); 19 return new _CustomHashMap<K, V>(equals, hashCode);
30 } 20 }
31 } 21 }
32 22
33 const int _MODIFICATION_COUNT_MASK = 0x3fffffff; 23 const int _MODIFICATION_COUNT_MASK = 0x3fffffff;
34 24
35 class _HashMap<K, V> implements HashMap<K, V> { 25 class _HashMapImpl<K, V> implements HashMap<K, V> {
36 static const int _INITIAL_CAPACITY = 8; 26 static const int _INITIAL_CAPACITY = 8;
37 27
38 int _elementCount = 0; 28 int _elementCount = 0;
39 List<_HashMapEntry> _buckets = new List(_INITIAL_CAPACITY); 29 List<_HashMapEntry> _buckets = new List(_INITIAL_CAPACITY);
40 int _modificationCount = 0; 30 int _modificationCount = 0;
41 31
42 int get length => _elementCount; 32 int get length => _elementCount;
43 bool get isEmpty => _elementCount == 0; 33 bool get isEmpty => _elementCount == 0;
44 bool get isNotEmpty => _elementCount != 0; 34 bool get isNotEmpty => _elementCount != 0;
45 35
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 137
148 V remove(Object key) { 138 V remove(Object key) {
149 int hashCode = key.hashCode; 139 int hashCode = key.hashCode;
150 List buckets = _buckets; 140 List buckets = _buckets;
151 int index = hashCode & (buckets.length - 1); 141 int index = hashCode & (buckets.length - 1);
152 _HashMapEntry entry = buckets[index]; 142 _HashMapEntry entry = buckets[index];
153 _HashMapEntry previous = null; 143 _HashMapEntry previous = null;
154 while (entry != null) { 144 while (entry != null) {
155 _HashMapEntry next = entry.next; 145 _HashMapEntry next = entry.next;
156 if (hashCode == entry.hashCode && entry.key == key) { 146 if (hashCode == entry.hashCode && entry.key == key) {
157 _removeEntry(entry, previous, index); 147 if (previous == null) {
148 buckets[index] = next;
149 } else {
150 previous.next = next;
151 }
158 _elementCount--; 152 _elementCount--;
159 _modificationCount = 153 _modificationCount =
160 (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; 154 (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
161 return entry.value; 155 return entry.value;
162 } 156 }
163 previous = entry; 157 previous = entry;
164 entry = next; 158 entry = next;
165 } 159 }
166 return null; 160 return null;
167 } 161 }
168 162
169 void clear() { 163 void clear() {
170 _elementCount = 0; 164 _elementCount = 0;
171 _buckets = new List(_INITIAL_CAPACITY); 165 _buckets = new List(_INITIAL_CAPACITY);
172 _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; 166 _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
173 } 167 }
174 168
175 void _removeEntry(_HashMapEntry entry,
176 _HashMapEntry previousInBucket,
177 int bucketIndex) {
178 if (previousInBucket == null) {
179 _buckets[bucketIndex] = entry.next;
180 } else {
181 previousInBucket.next = entry.next;
182 }
183 }
184
185 void _addEntry(List buckets, int index, int length, 169 void _addEntry(List buckets, int index, int length,
186 K key, V value, int hashCode) { 170 K key, V value, int hashCode) {
187 _HashMapEntry entry = 171 _HashMapEntry entry =
188 new _HashMapEntry(key, value, hashCode, buckets[index]); 172 new _HashMapEntry(key, value, hashCode, buckets[index]);
189 buckets[index] = entry; 173 buckets[index] = entry;
190 int newElements = _elementCount + 1; 174 int newElements = _elementCount + 1;
191 _elementCount = newElements; 175 _elementCount = newElements;
192 // If we end up with more than 75% non-empty entries, we 176 // If we end up with more than 75% non-empty entries, we
193 // resize the backing store. 177 // resize the backing store.
194 if ((newElements << 2) > ((length << 1) + length)) _resize(); 178 if ((newElements << 2) > ((length << 1) + length)) _resize();
(...skipping 15 matching lines...) Expand all
210 newBuckets[index] = entry; 194 newBuckets[index] = entry;
211 entry = next; 195 entry = next;
212 } 196 }
213 } 197 }
214 _buckets = newBuckets; 198 _buckets = newBuckets;
215 } 199 }
216 200
217 String toString() => Maps.mapToString(this); 201 String toString() => Maps.mapToString(this);
218 } 202 }
219 203
220 class _CustomHashMap<K, V> extends _HashMap<K, V> { 204 class _CustomHashMap<K, V> extends _HashMapImpl<K, V> {
221 final _Equality<K> _equals; 205 final _Equality<K> _equals;
222 final _Hasher<K> _hashCode; 206 final _Hasher<K> _hashCode;
223 final _Predicate _validKey; 207 _CustomHashMap(this._equals, this._hashCode);
224 _CustomHashMap(this._equals, this._hashCode, validKey)
225 : _validKey = (validKey != null) ? validKey : new _TypeTest<K>().test;
226 208
227 bool containsKey(Object key) { 209 bool containsKey(Object key) {
228 if (!_validKey(key)) return false;
229 int hashCode = _hashCode(key); 210 int hashCode = _hashCode(key);
230 List buckets = _buckets; 211 List buckets = _buckets;
231 int index = hashCode & (buckets.length - 1); 212 int index = hashCode & (buckets.length - 1);
232 _HashMapEntry entry = buckets[index]; 213 _HashMapEntry entry = buckets[index];
233 while (entry != null) { 214 while (entry != null) {
234 if (hashCode == entry.hashCode && _equals(entry.key, key)) return true; 215 if (hashCode == entry.hashCode && _equals(entry.key, key)) return true;
235 entry = entry.next; 216 entry = entry.next;
236 } 217 }
237 return false; 218 return false;
238 } 219 }
239 220
240 V operator[](Object key) { 221 V operator[](Object key) {
241 if (!_validKey(key)) return null;
242 int hashCode = _hashCode(key); 222 int hashCode = _hashCode(key);
243 List buckets = _buckets; 223 List buckets = _buckets;
244 int index = hashCode & (buckets.length - 1); 224 int index = hashCode & (buckets.length - 1);
245 _HashMapEntry entry = buckets[index]; 225 _HashMapEntry entry = buckets[index];
246 while (entry != null) { 226 while (entry != null) {
247 if (hashCode == entry.hashCode && _equals(entry.key, key)) { 227 if (hashCode == entry.hashCode && _equals(entry.key, key)) {
248 return entry.value; 228 return entry.value;
249 } 229 }
250 entry = entry.next; 230 entry = entry.next;
251 } 231 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 V value = ifAbsent(); 264 V value = ifAbsent();
285 if (stamp == _modificationCount) { 265 if (stamp == _modificationCount) {
286 _addEntry(buckets, index, length, key, value, hashCode); 266 _addEntry(buckets, index, length, key, value, hashCode);
287 } else { 267 } else {
288 this[key] = value; 268 this[key] = value;
289 } 269 }
290 return value; 270 return value;
291 } 271 }
292 272
293 V remove(Object key) { 273 V remove(Object key) {
294 if (!_validKey(key)) return null;
295 int hashCode = _hashCode(key); 274 int hashCode = _hashCode(key);
296 List buckets = _buckets; 275 List buckets = _buckets;
297 int index = hashCode & (buckets.length - 1); 276 int index = hashCode & (buckets.length - 1);
298 _HashMapEntry entry = buckets[index]; 277 _HashMapEntry entry = buckets[index];
299 _HashMapEntry previous = null; 278 _HashMapEntry previous = null;
300 while (entry != null) { 279 while (entry != null) {
301 _HashMapEntry next = entry.next; 280 _HashMapEntry next = entry.next;
302 if (hashCode == entry.hashCode && _equals(entry.key, key)) { 281 if (hashCode == entry.hashCode && _equals(entry.key, key)) {
303 _removeEntry(entry, previous, index); 282 if (previous == null) {
283 buckets[index] = next;
284 } else {
285 previous.next = next;
286 }
304 _elementCount--; 287 _elementCount--;
305 _modificationCount = 288 _modificationCount =
306 (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; 289 (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
307 return entry.value; 290 return entry.value;
308 } 291 }
309 previous = entry; 292 previous = entry;
310 entry = next; 293 entry = next;
311 } 294 }
312 return null; 295 return null;
313 } 296 }
314 297
315 String toString() => Maps.mapToString(this); 298 String toString() => Maps.mapToString(this);
316 } 299 }
317 300
318 class _IdentityHashMap<K, V> extends _HashMap<K, V> { 301 class _IdentityHashMap<K, V> extends _HashMapImpl<K, V> {
319 bool containsKey(Object key) { 302 bool containsKey(Object key) {
320 int hashCode = key.hashCode; 303 int hashCode = key.hashCode;
321 List buckets = _buckets; 304 List buckets = _buckets;
322 int index = hashCode & (buckets.length - 1); 305 int index = hashCode & (buckets.length - 1);
323 _HashMapEntry entry = buckets[index]; 306 _HashMapEntry entry = buckets[index];
324 while (entry != null) { 307 while (entry != null) {
325 if (hashCode == entry.hashCode && identical(entry.key, key)) return true; 308 if (hashCode == entry.hashCode && identical(entry.key, key)) return true;
326 entry = entry.next; 309 entry = entry.next;
327 } 310 }
328 return false; 311 return false;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 365
383 V remove(Object key) { 366 V remove(Object key) {
384 int hashCode = key.hashCode; 367 int hashCode = key.hashCode;
385 List buckets = _buckets; 368 List buckets = _buckets;
386 int index = hashCode & (buckets.length - 1); 369 int index = hashCode & (buckets.length - 1);
387 _HashMapEntry entry = buckets[index]; 370 _HashMapEntry entry = buckets[index];
388 _HashMapEntry previous = null; 371 _HashMapEntry previous = null;
389 while (entry != null) { 372 while (entry != null) {
390 _HashMapEntry next = entry.next; 373 _HashMapEntry next = entry.next;
391 if (hashCode == entry.hashCode && identical(entry.key, key)) { 374 if (hashCode == entry.hashCode && identical(entry.key, key)) {
392 _removeEntry(entry, previous, index); 375 if (previous == null) {
376 buckets[index] = next;
377 } else {
378 previous.next = next;
379 }
393 _elementCount--; 380 _elementCount--;
394 _modificationCount = 381 _modificationCount =
395 (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; 382 (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
396 return entry.value; 383 return entry.value;
397 } 384 }
398 previous = entry; 385 previous = entry;
399 entry = next; 386 entry = next;
400 } 387 }
401 return null; 388 return null;
402 } 389 }
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 LinkedHashMap<dynamic, V> _map; 589 LinkedHashMap<dynamic, V> _map;
603 _LinkedHashMapValueIterable(this._map); 590 _LinkedHashMapValueIterable(this._map);
604 Iterator<K> get iterator => new _LinkedHashMapValueIterator<V>(_map); 591 Iterator<K> get iterator => new _LinkedHashMapValueIterator<V>(_map);
605 bool contains(V value) => _map.containsValue(value); 592 bool contains(V value) => _map.containsValue(value);
606 bool get isEmpty => _map.isEmpty; 593 bool get isEmpty => _map.isEmpty;
607 bool get isNotEmpty => _map.isNotEmpty; 594 bool get isNotEmpty => _map.isNotEmpty;
608 int get length => _map.length; 595 int get length => _map.length;
609 } 596 }
610 597
611 abstract class _LinkedHashMapIterator<T> implements Iterator<T> { 598 abstract class _LinkedHashMapIterator<T> implements Iterator<T> {
612 final LinkedHashMap _map; 599 final _LinkedHashMap _map;
613 var _next; 600 var _next;
614 T _current; 601 T _current;
615 int _modificationCount; 602 int _modificationCount;
616 _LinkedHashMapIterator(LinkedHashMap map) 603 _LinkedHashMapIterator(_LinkedHashMap map)
617 : _map = map, 604 : _map = map,
618 _current = null, 605 _current = null,
619 _next = map._nextEntry, 606 _next = map._nextEntry,
620 _modificationCount = map._modificationCount; 607 _modificationCount = map._modificationCount;
621 608
622 bool moveNext() { 609 bool moveNext() {
623 if (_modificationCount != _map._modificationCount) { 610 if (_modificationCount != _map._modificationCount) {
624 throw new ConcurrentModificationError(_map); 611 throw new ConcurrentModificationError(_map);
625 } 612 }
626 if (identical(_map, _next)) { 613 if (identical(_map, _next)) {
627 _current = null; 614 _current = null;
628 return false; 615 return false;
629 } 616 }
630 _LinkedHashMapEntry entry = _next; 617 _LinkedHashMapEntry entry = _next;
631 _next = entry._nextEntry; 618 _next = entry._nextEntry;
632 _current = _getValue(entry); 619 _current = _getValue(entry);
633 return true; 620 return true;
634 } 621 }
635 622
636 T _getValue(_LinkedHashMapEntry entry); 623 T _getValue(_LinkedHashMapEntry entry);
637 624
638 T get current => _current; 625 T get current => _current;
639 } 626 }
640 627
641 class _LinkedHashMapKeyIterator<K> extends _LinkedHashMapIterator<K> { 628 class _LinkedHashMapKeyIterator<K> extends _LinkedHashMapIterator<K> {
642 _LinkedHashMapKeyIterator(LinkedHashMap map) : super(map); 629 _LinkedHashMapKeyIterator(_LinkedHashMap map) : super(map);
643 K _getValue(_LinkedHashMapEntry entry) => entry.key; 630 K _getValue(_LinkedHashMapEntry entry) => entry.key;
644 } 631 }
645 632
646 class _LinkedHashMapValueIterator<V> extends _LinkedHashMapIterator<V> { 633 class _LinkedHashMapValueIterator<V> extends _LinkedHashMapIterator<V> {
647 _LinkedHashMapValueIterator(LinkedHashMap map) : super(map); 634 _LinkedHashMapValueIterator(_LinkedHashMap map) : super(map);
648 V _getValue(_LinkedHashMapEntry entry) => entry.value; 635 V _getValue(_LinkedHashMapEntry entry) => entry.value;
649 } 636 }
650 637
651 638
652 /** 639 /**
653 * A hash-based map that iterates keys and values in key insertion order. 640 * A hash-based map that iterates keys and values in key insertion order.
654 */ 641 */
655 patch class LinkedHashMap<K, V> { 642 patch class LinkedHashMap<K, V> {
643 static const int _INITIAL_CAPACITY = 8;
644 static const int _MODIFICATION_COUNT_MASK = 0x3fffffff;
645
646 int _elementCount = 0;
647 List<_HashMapEntry> _buckets = new List(_INITIAL_CAPACITY);
648 int _modificationCount = 0;
649
656 var _nextEntry; 650 var _nextEntry;
657 var _previousEntry; 651 var _previousEntry;
658 652
659 /* patch */ factory LinkedHashMap({ bool equals(K key1, K key2), 653 /* patch */ LinkedHashMap() {
660 int hashCode(K key), 654 _nextEntry = _previousEntry = this;
661 bool isValidKey(potentialKey) }) { 655 }
662 if (isValidKey == null) { 656
663 if (hashCode == null) { 657 /* patch */ int get length => _elementCount;
664 if (equals == null) { 658 /* patch */ bool get isEmpty => _elementCount == 0;
665 return new _LinkedHashMap<K, V>(); 659 /* patch */ bool get isNotEmpty => _elementCount != 0;
666 } 660
667 if (identical(identical, equals)) { 661 /* patch */ Iterable<K> get keys => new _LinkedHashMapKeyIterable<K>(this);
668 return new _LinkedIdentityHashMap<K, V>(); 662 /* patch */ Iterable<V> get values => new _LinkedHashMapValueIterable<V>(this) ;
669 } 663
670 hashCode = _defaultHashCode; 664 /* patch */ bool containsKey(Object key) {
671 } else if (equals == null) { 665 int hashCode = key.hashCode;
672 equals = _defaultEquals; 666 List buckets = _buckets;
673 } 667 int index = hashCode & (buckets.length - 1);
674 } else { 668 _HashMapEntry entry = buckets[index];
675 if (hashCode == null) { 669 while (entry != null) {
676 hashCode = _defaultHashCode; 670 if (hashCode == entry.hashCode && entry.key == key) return true;
677 } 671 entry = entry.next;
678 if (equals == null) {
679 equals = _defaultEquals;
680 }
681 } 672 }
682 return new _LinkedCustomHashMap<K, V>(equals, hashCode, isValidKey); 673 return false;
683 } 674 }
684 }
685 675
686 // Methods that are exactly the same in all three linked hash map variants. 676 /* patch */ bool containsValue(Object value) {
687 abstract class _LinkedHashMapMixin<K, V> implements LinkedHashMap<K, V> { 677 var cursor = _nextEntry;
688 var _nextEntry;
689 var _previousEntry;
690
691 bool containsValue(Object value) {
692 int modificationCount = _modificationCount; 678 int modificationCount = _modificationCount;
693 var cursor = _nextEntry;
694 while (!identical(cursor, this)) { 679 while (!identical(cursor, this)) {
695 _HashMapEntry entry = cursor; 680 _HashMapEntry entry = cursor;
696 if (entry.value == value) return true; 681 if (entry.value == value) return true;
697 if (modificationCount != _modificationCount) {
698 throw new ConcurrentModificationError(this);
699 }
700 cursor = cursor._nextEntry; 682 cursor = cursor._nextEntry;
701 } 683 }
702 return false; 684 return false;
703 } 685 }
704 686
705 void forEach(void action(K key, V value)) { 687 /* patch */ V operator[](Object key) {
706 int modificationCount = _modificationCount; 688 int hashCode = key.hashCode;
689 List buckets = _buckets;
690 int index = hashCode & (buckets.length - 1);
691 _HashMapEntry entry = buckets[index];
692 while (entry != null) {
693 if (hashCode == entry.hashCode && entry.key == key) {
694 return entry.value;
695 }
696 entry = entry.next;
697 }
698 return null;
699 }
700
701 /* patch */ void operator []=(K key, V value) {
702 int hashCode = key.hashCode;
703 List buckets = _buckets;
704 int length = buckets.length;
705 int index = hashCode & (length - 1);
706 _HashMapEntry entry = buckets[index];
707 while (entry != null) {
708 if (hashCode == entry.hashCode && entry.key == key) {
709 entry.value = value;
710 return;
711 }
712 entry = entry.next;
713 }
714 _addEntry(buckets, index, length, key, value, hashCode);
715 }
716
717 /* patch */ V putIfAbsent(K key, V ifAbsent()) {
718 int hashCode = key.hashCode;
719 List buckets = _buckets;
720 int length = buckets.length;
721 int index = hashCode & (length - 1);
722 _HashMapEntry entry = buckets[index];
723 while (entry != null) {
724 if (hashCode == entry.hashCode && entry.key == key) {
725 return entry.value;
726 }
727 entry = entry.next;
728 }
729 int stamp = _modificationCount;
730 V value = ifAbsent();
731 if (stamp == _modificationCount) {
732 _addEntry(buckets, index, length, key, value, hashCode);
733 } else {
734 this[key] = value;
735 }
736 return value;
737 }
738
739 /* patch */ void addAll(Map<K, V> other) {
740 other.forEach((K key, V value) {
741 this[key] = value;
742 });
743 }
744
745 /* patch */ void forEach(void action(K key, V value)) {
746 int stamp = _modificationCount;
707 var cursor = _nextEntry; 747 var cursor = _nextEntry;
708 while (!identical(cursor, this)) { 748 while (!identical(cursor, this)) {
709 _HashMapEntry entry = cursor; 749 _HashMapEntry entry = cursor;
710 action(entry.key, entry.value); 750 action(entry.key, entry.value);
711 if (modificationCount != _modificationCount) { 751 if (stamp != _modificationCount) {
712 throw new ConcurrentModificationError(this); 752 throw new ConcurrentModificationError(this);
713 } 753 }
714 cursor = cursor._nextEntry; 754 cursor = cursor._nextEntry;
715 } 755 }
716 } 756 }
717 757
718 void clear() { 758 /* patch */ V remove(Object key) {
759 int hashCode = key.hashCode;
760 List buckets = _buckets;
761 int index = hashCode & (buckets.length - 1);
762 _LinkedHashMapEntry entry = buckets[index];
763 _HashMapEntry previous = null;
764 while (entry != null) {
765 _HashMapEntry next = entry.next;
766 if (hashCode == entry.hashCode && entry.key == key) {
767 if (previous == null) {
768 buckets[index] = next;
769 } else {
770 previous.next = next;
771 }
772 entry._previousEntry._nextEntry = entry._nextEntry;
773 entry._nextEntry._previousEntry = entry._previousEntry;
774 entry._nextEntry = entry._previousEntry = null;
775 _elementCount--;
776 _modificationCount =
777 (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
778 return entry.value;
779 }
780 previous = entry;
781 entry = next;
782 }
783 return null;
784 }
785
786 /* patch */ void clear() {
787 _elementCount = 0;
719 _nextEntry = _previousEntry = this; 788 _nextEntry = _previousEntry = this;
720 _elementCount = 0; 789 _buckets = new List(_INITIAL_CAPACITY);
721 _buckets = new List(_HashMap._INITIAL_CAPACITY);
722 _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; 790 _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
723 } 791 }
724 792
725 void _addEntry(List buckets, int index, int length, 793 void _addEntry(List buckets, int index, int length,
726 K key, V value, int hashCode) { 794 K key, V value, int hashCode) {
727 _HashMapEntry entry = 795 _HashMapEntry entry =
728 new _LinkedHashMapEntry(key, value, hashCode, buckets[index], 796 new _LinkedHashMapEntry(key, value, hashCode, buckets[index],
729 _previousEntry, this); 797 _previousEntry, this);
730 buckets[index] = entry; 798 buckets[index] = entry;
731 int newElements = _elementCount + 1; 799 int newElements = _elementCount + 1;
732 _elementCount = newElements; 800 _elementCount = newElements;
733 // If we end up with more than 75% non-empty entries, we 801 // If we end up with more than 75% non-empty entries, we
734 // resize the backing store. 802 // resize the backing store.
735 if ((newElements << 2) > ((length << 1) + length)) _resize(); 803 if ((newElements << 2) > ((length << 1) + length)) _resize();
736 _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK; 804 _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
737 } 805 }
738 806
739 void _removeEntry(_LinkedHashMapEntry entry, 807 void _resize() {
740 _HashMapEntry previousInBucket, 808 List oldBuckets = _buckets;
741 int bucketIndex) { 809 int oldLength = oldBuckets.length;
742 var previousInChain = entry._previousEntry; 810 int newLength = oldLength << 1;
743 var nextInChain = entry._nextEntry; 811 List newBuckets = new List(newLength);
744 previousInChain._nextEntry = nextInChain; 812 for (int i = 0; i < oldLength; i++) {
745 nextInChain._previousEntry = previousInChain; 813 _HashMapEntry entry = oldBuckets[i];
746 if (previousInBucket == null) { 814 while (entry != null) {
747 _buckets[bucketIndex] = entry.next; 815 _HashMapEntry next = entry.next;
748 } else { 816 int hashCode = entry.hashCode;
749 previousInBucket.next = entry.next; 817 int index = hashCode & (newLength - 1);
818 entry.next = newBuckets[index];
819 newBuckets[index] = entry;
820 entry = next;
821 }
750 } 822 }
751 } 823 _buckets = newBuckets;
752
753
754 Iterable<K> get keys => new _LinkedHashMapKeyIterable<K>(this);
755 Iterable<V> get values => new _LinkedHashMapValueIterable<V>(this);
756 }
757
758 class _LinkedHashMap<K, V> extends _HashMap<K, V>
759 with _LinkedHashMapMixin<K, V> {
760 _LinkedHashMap() {
761 _nextEntry = _previousEntry = this;
762 } 824 }
763 } 825 }
764 826
765 class _LinkedIdentityHashMap<K, V> extends _IdentityHashMap<K, V>
766 with _LinkedHashMapMixin<K, V> {
767 _LinkedIdentityHashMap() {
768 _nextEntry = _previousEntry = this;
769 }
770 }
771
772 class _LinkedCustomHashMap<K, V> extends _CustomHashMap<K, V>
773 with _LinkedHashMapMixin<K, V> {
774 _LinkedCustomHashMap(bool equals(K key1, K key2),
775 int hashCode(K key),
776 bool isValidKey(potentialKey))
777 : super(equals, hashCode, isValidKey) {
778 _nextEntry = _previousEntry = this;
779 }
780 }
781
782
783 patch class LinkedHashSet<E> extends _HashSetBase<E> { 827 patch class LinkedHashSet<E> extends _HashSetBase<E> {
784 static const int _INITIAL_CAPACITY = 8; 828 static const int _INITIAL_CAPACITY = 8;
785 _LinkedHashTable<E> _table; 829 _LinkedHashTable<E> _table;
786 830
787 /* patch */ LinkedHashSet() { 831 /* patch */ LinkedHashSet() {
788 _table = new _LinkedHashTable(_INITIAL_CAPACITY); 832 _table = new _LinkedHashTable(_INITIAL_CAPACITY);
789 _table._container = this; 833 _table._container = this;
790 } 834 }
791 835
792 // Iterable. 836 // Iterable.
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
1473 1517
1474 _LinkedHashMapTable() : super(_INITIAL_CAPACITY); 1518 _LinkedHashMapTable() : super(_INITIAL_CAPACITY);
1475 1519
1476 V _value(int offset) => _table[offset + _VALUE_INDEX]; 1520 V _value(int offset) => _table[offset + _VALUE_INDEX];
1477 void _setValue(int offset, V value) { _table[offset + _VALUE_INDEX] = value; } 1521 void _setValue(int offset, V value) { _table[offset + _VALUE_INDEX] = value; }
1478 1522
1479 _copyEntry(List oldTable, int fromOffset, int toOffset) { 1523 _copyEntry(List oldTable, int fromOffset, int toOffset) {
1480 _table[toOffset + _VALUE_INDEX] = oldTable[fromOffset + _VALUE_INDEX]; 1524 _table[toOffset + _VALUE_INDEX] = oldTable[fromOffset + _VALUE_INDEX];
1481 } 1525 }
1482 } 1526 }
OLDNEW
« no previous file with comments | « pkg/serialization/test/polyfill_identity_map_test.dart ('k') | sdk/lib/_internal/lib/collection_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698