| OLD | NEW |
| 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 final _HashMapTable<K, V> _hashTable = new _HashMapTable<K, V>(); | 6 final _HashMapTable<K, V> _hashTable = new _HashMapTable<K, V>(); |
| 7 | 7 |
| 8 /* patch */ HashMap() { | 8 /* patch */ HashMap() { |
| 9 _hashTable._container = this; | 9 _hashTable._container = this; |
| 10 } | 10 } |
| 11 | 11 |
| 12 /* patch */ bool containsKey(K key) { | 12 /* patch */ bool containsKey(Object key) { |
| 13 return _hashTable._get(key) >= 0; | 13 return _hashTable._get(key) >= 0; |
| 14 } | 14 } |
| 15 | 15 |
| 16 /* patch */ bool containsValue(V value) { | 16 /* patch */ bool containsValue(Object value) { |
| 17 List table = _hashTable._table; | 17 List table = _hashTable._table; |
| 18 int entrySize = _hashTable._entrySize; | 18 int entrySize = _hashTable._entrySize; |
| 19 for (int offset = 0; offset < table.length; offset += entrySize) { | 19 for (int offset = 0; offset < table.length; offset += entrySize) { |
| 20 if (!_hashTable._isFree(table[offset]) && | 20 if (!_hashTable._isFree(table[offset]) && |
| 21 _hashTable._value(offset) == value) { | 21 _hashTable._value(offset) == value) { |
| 22 return true; | 22 return true; |
| 23 } | 23 } |
| 24 } | 24 } |
| 25 return false; | 25 return false; |
| 26 } | 26 } |
| 27 | 27 |
| 28 /* patch */ void addAll(Map<K, V> other) { | 28 /* patch */ void addAll(Map<K, V> other) { |
| 29 other.forEach((K key, V value) { | 29 other.forEach((K key, V value) { |
| 30 int offset = _hashTable._put(key); | 30 int offset = _hashTable._put(key); |
| 31 _hashTable._setValue(offset, value); | 31 _hashTable._setValue(offset, value); |
| 32 _hashTable._checkCapacity(); | 32 _hashTable._checkCapacity(); |
| 33 }); | 33 }); |
| 34 } | 34 } |
| 35 | 35 |
| 36 /* patch */ V operator [](K key) { | 36 /* patch */ V operator [](Object key) { |
| 37 int offset = _hashTable._get(key); | 37 int offset = _hashTable._get(key); |
| 38 if (offset >= 0) return _hashTable._value(offset); | 38 if (offset >= 0) return _hashTable._value(offset); |
| 39 return null; | 39 return null; |
| 40 } | 40 } |
| 41 | 41 |
| 42 /* patch */ void operator []=(K key, V value) { | 42 /* patch */ void operator []=(K key, V value) { |
| 43 int offset = _hashTable._put(key); | 43 int offset = _hashTable._put(key); |
| 44 _hashTable._setValue(offset, value); | 44 _hashTable._setValue(offset, value); |
| 45 _hashTable._checkCapacity(); | 45 _hashTable._checkCapacity(); |
| 46 } | 46 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 67 } else { | 67 } else { |
| 68 // The table might have changed, so we can't trust [offset] any more. | 68 // The table might have changed, so we can't trust [offset] any more. |
| 69 // Do another lookup before setting the value. | 69 // Do another lookup before setting the value. |
| 70 offset = _hashTable._put(key); | 70 offset = _hashTable._put(key); |
| 71 _hashTable._setValue(offset, value); | 71 _hashTable._setValue(offset, value); |
| 72 _hashTable._checkCapacity(); | 72 _hashTable._checkCapacity(); |
| 73 } | 73 } |
| 74 return value; | 74 return value; |
| 75 } | 75 } |
| 76 | 76 |
| 77 /* patch */ V remove(K key) { | 77 /* patch */ V remove(Object key) { |
| 78 int offset = _hashTable._remove(key); | 78 int offset = _hashTable._remove(key); |
| 79 if (offset < 0) return null; | 79 if (offset < 0) return null; |
| 80 V oldValue = _hashTable._value(offset); | 80 V oldValue = _hashTable._value(offset); |
| 81 _hashTable._setValue(offset, null); | 81 _hashTable._setValue(offset, null); |
| 82 _hashTable._checkCapacity(); | 82 _hashTable._checkCapacity(); |
| 83 return oldValue; | 83 return oldValue; |
| 84 } | 84 } |
| 85 | 85 |
| 86 /* patch */ void clear() { | 86 /* patch */ void clear() { |
| 87 _hashTable._clear(); | 87 _hashTable._clear(); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 /** | 196 /** |
| 197 * A hash-based map that iterates keys and values in key insertion order. | 197 * A hash-based map that iterates keys and values in key insertion order. |
| 198 */ | 198 */ |
| 199 patch class LinkedHashMap<K, V> { | 199 patch class LinkedHashMap<K, V> { |
| 200 final _LinkedHashMapTable _hashTable; | 200 final _LinkedHashMapTable _hashTable; |
| 201 | 201 |
| 202 /* patch */ LinkedHashMap() : _hashTable = new _LinkedHashMapTable<K, V>() { | 202 /* patch */ LinkedHashMap() : _hashTable = new _LinkedHashMapTable<K, V>() { |
| 203 _hashTable._container = this; | 203 _hashTable._container = this; |
| 204 } | 204 } |
| 205 | 205 |
| 206 /* patch */ bool containsKey(K key) { | 206 /* patch */ bool containsKey(Object key) { |
| 207 return _hashTable._get(key) >= 0; | 207 return _hashTable._get(key) >= 0; |
| 208 } | 208 } |
| 209 | 209 |
| 210 /* patch */ bool containsValue(V value) { | 210 /* patch */ bool containsValue(Object value) { |
| 211 int modificationCount = _hashTable._modificationCount; | 211 int modificationCount = _hashTable._modificationCount; |
| 212 for (int offset = _hashTable._next(_LinkedHashTable._HEAD_OFFSET); | 212 for (int offset = _hashTable._next(_LinkedHashTable._HEAD_OFFSET); |
| 213 offset != _LinkedHashTable._HEAD_OFFSET; | 213 offset != _LinkedHashTable._HEAD_OFFSET; |
| 214 offset = _hashTable._next(offset)) { | 214 offset = _hashTable._next(offset)) { |
| 215 if (_hashTable._value(offset) == value) { | 215 if (_hashTable._value(offset) == value) { |
| 216 return true; | 216 return true; |
| 217 } | 217 } |
| 218 // The == call may modify the table. | 218 // The == call may modify the table. |
| 219 _hashTable._checkModification(modificationCount); | 219 _hashTable._checkModification(modificationCount); |
| 220 } | 220 } |
| 221 return false; | 221 return false; |
| 222 } | 222 } |
| 223 | 223 |
| 224 /* patch */ void addAll(Map<K, V> other) { | 224 /* patch */ void addAll(Map<K, V> other) { |
| 225 other.forEach((K key, V value) { | 225 other.forEach((K key, V value) { |
| 226 int offset = _hashTable._put(key); | 226 int offset = _hashTable._put(key); |
| 227 _hashTable._setValue(offset, value); | 227 _hashTable._setValue(offset, value); |
| 228 _hashTable._checkCapacity(); | 228 _hashTable._checkCapacity(); |
| 229 }); | 229 }); |
| 230 } | 230 } |
| 231 | 231 |
| 232 /* patch */ V operator [](K key) { | 232 /* patch */ V operator [](Object key) { |
| 233 int offset = _hashTable._get(key); | 233 int offset = _hashTable._get(key); |
| 234 if (offset >= 0) return _hashTable._value(offset); | 234 if (offset >= 0) return _hashTable._value(offset); |
| 235 return null; | 235 return null; |
| 236 } | 236 } |
| 237 | 237 |
| 238 /* patch */ void operator []=(K key, V value) { | 238 /* patch */ void operator []=(K key, V value) { |
| 239 int offset = _hashTable._put(key); | 239 int offset = _hashTable._put(key); |
| 240 _hashTable._setValue(offset, value); | 240 _hashTable._setValue(offset, value); |
| 241 _hashTable._checkCapacity(); | 241 _hashTable._checkCapacity(); |
| 242 } | 242 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 264 } else { | 264 } else { |
| 265 // The table might have changed, so we can't trust [offset] any more. | 265 // The table might have changed, so we can't trust [offset] any more. |
| 266 // Do another lookup before setting the value. | 266 // Do another lookup before setting the value. |
| 267 offset = _hashTable._put(key); | 267 offset = _hashTable._put(key); |
| 268 _hashTable._setValue(offset, value); | 268 _hashTable._setValue(offset, value); |
| 269 _hashTable._checkCapacity(); | 269 _hashTable._checkCapacity(); |
| 270 } | 270 } |
| 271 return value; | 271 return value; |
| 272 } | 272 } |
| 273 | 273 |
| 274 /* patch */ V remove(K key) { | 274 /* patch */ V remove(Object key) { |
| 275 int offset = _hashTable._remove(key); | 275 int offset = _hashTable._remove(key); |
| 276 if (offset < 0) return null; | 276 if (offset < 0) return null; |
| 277 Object oldValue = _hashTable._value(offset); | 277 Object oldValue = _hashTable._value(offset); |
| 278 _hashTable._setValue(offset, null); | 278 _hashTable._setValue(offset, null); |
| 279 _hashTable._checkCapacity(); | 279 _hashTable._checkCapacity(); |
| 280 return oldValue; | 280 return oldValue; |
| 281 } | 281 } |
| 282 | 282 |
| 283 /* patch */ void clear() { | 283 /* patch */ void clear() { |
| 284 _hashTable._clear(); | 284 _hashTable._clear(); |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 */ | 637 */ |
| 638 void _copyEntry(List fromTable, int fromOffset, int toOffset) {} | 638 void _copyEntry(List fromTable, int fromOffset, int toOffset) {} |
| 639 | 639 |
| 640 // The following three methods are for simple get/set/remove operations. | 640 // The following three methods are for simple get/set/remove operations. |
| 641 // They only affect the key of an entry. The remaining fields must be | 641 // They only affect the key of an entry. The remaining fields must be |
| 642 // filled by the caller. | 642 // filled by the caller. |
| 643 | 643 |
| 644 /** | 644 /** |
| 645 * Returns the offset of a key in [_table], or negative if it's not there. | 645 * Returns the offset of a key in [_table], or negative if it's not there. |
| 646 */ | 646 */ |
| 647 int _get(K key) { | 647 int _get(Object key) { |
| 648 return _probeForLookup(_hashCodeOf(key), key); | 648 return _probeForLookup(_hashCodeOf(key), key); |
| 649 } | 649 } |
| 650 | 650 |
| 651 /** | 651 /** |
| 652 * Puts the key into the table and returns its offset into [_table]. | 652 * Puts the key into the table and returns its offset into [_table]. |
| 653 * | 653 * |
| 654 * If [_entrySize] is greater than 1, the caller should fill the | 654 * If [_entrySize] is greater than 1, the caller should fill the |
| 655 * remaining fields. | 655 * remaining fields. |
| 656 * | 656 * |
| 657 * Remember to call [_checkCapacity] after using this method. | 657 * Remember to call [_checkCapacity] after using this method. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 671 return offset; | 671 return offset; |
| 672 } | 672 } |
| 673 | 673 |
| 674 /** | 674 /** |
| 675 * Removes a key from the table and returns its offset into [_table]. | 675 * Removes a key from the table and returns its offset into [_table]. |
| 676 * | 676 * |
| 677 * Returns null if the key was not in the table. | 677 * Returns null if the key was not in the table. |
| 678 * If [_entrySize] is greater than 1, the caller should clean up the | 678 * If [_entrySize] is greater than 1, the caller should clean up the |
| 679 * remaining fields. | 679 * remaining fields. |
| 680 */ | 680 */ |
| 681 int _remove(K key) { | 681 int _remove(Object key) { |
| 682 int offset = _probeForLookup(_hashCodeOf(key), key); | 682 int offset = _probeForLookup(_hashCodeOf(key), key); |
| 683 if (offset >= 0) { | 683 if (offset >= 0) { |
| 684 _deleteEntry(offset); | 684 _deleteEntry(offset); |
| 685 } | 685 } |
| 686 return offset; | 686 return offset; |
| 687 } | 687 } |
| 688 | 688 |
| 689 /** Clears the table completely, leaving it empty. */ | 689 /** Clears the table completely, leaving it empty. */ |
| 690 void _clear() { | 690 void _clear() { |
| 691 if (_elementCount == 0) return; | 691 if (_elementCount == 0) return; |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 | 1001 |
| 1002 _LinkedHashMapTable() : super(_INITIAL_CAPACITY); | 1002 _LinkedHashMapTable() : super(_INITIAL_CAPACITY); |
| 1003 | 1003 |
| 1004 V _value(int offset) => _table[offset + _VALUE_INDEX]; | 1004 V _value(int offset) => _table[offset + _VALUE_INDEX]; |
| 1005 void _setValue(int offset, V value) { _table[offset + _VALUE_INDEX] = value; } | 1005 void _setValue(int offset, V value) { _table[offset + _VALUE_INDEX] = value; } |
| 1006 | 1006 |
| 1007 _copyEntry(List oldTable, int fromOffset, int toOffset) { | 1007 _copyEntry(List oldTable, int fromOffset, int toOffset) { |
| 1008 _table[toOffset + _VALUE_INDEX] = oldTable[fromOffset + _VALUE_INDEX]; | 1008 _table[toOffset + _VALUE_INDEX] = oldTable[fromOffset + _VALUE_INDEX]; |
| 1009 } | 1009 } |
| 1010 } | 1010 } |
| OLD | NEW |