| 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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 /** | 192 /** |
| 193 * A hash-based map that iterates keys and values in key insertion order. | 193 * A hash-based map that iterates keys and values in key insertion order. |
| 194 */ | 194 */ |
| 195 patch class LinkedHashMap<K, V> { | 195 patch class LinkedHashMap<K, V> { |
| 196 final _LinkedHashMapTable _hashTable; | 196 final _LinkedHashMapTable _hashTable; |
| 197 | 197 |
| 198 /* patch */ LinkedHashMap() : _hashTable = new _LinkedHashMapTable<K, V>() { | 198 /* patch */ LinkedHashMap() : _hashTable = new _LinkedHashMapTable<K, V>() { |
| 199 _hashTable._container = this; | 199 _hashTable._container = this; |
| 200 } | 200 } |
| 201 | 201 |
| 202 /* patch */ bool containsKey(K key) { | 202 /* patch */ bool containsKey(Object key) { |
| 203 return _hashTable._get(key) >= 0; | 203 return _hashTable._get(key) >= 0; |
| 204 } | 204 } |
| 205 | 205 |
| 206 /* patch */ bool containsValue(V value) { | 206 /* patch */ bool containsValue(Object value) { |
| 207 int modificationCount = _hashTable._modificationCount; | 207 int modificationCount = _hashTable._modificationCount; |
| 208 for (int offset = _hashTable._next(_LinkedHashTable._HEAD_OFFSET); | 208 for (int offset = _hashTable._next(_LinkedHashTable._HEAD_OFFSET); |
| 209 offset != _LinkedHashTable._HEAD_OFFSET; | 209 offset != _LinkedHashTable._HEAD_OFFSET; |
| 210 offset = _hashTable._next(offset)) { | 210 offset = _hashTable._next(offset)) { |
| 211 if (_hashTable._value(offset) == value) { | 211 if (_hashTable._value(offset) == value) { |
| 212 return true; | 212 return true; |
| 213 } | 213 } |
| 214 // The == call may modify the table. | 214 // The == call may modify the table. |
| 215 _hashTable._checkModification(modificationCount); | 215 _hashTable._checkModification(modificationCount); |
| 216 } | 216 } |
| 217 return false; | 217 return false; |
| 218 } | 218 } |
| 219 | 219 |
| 220 /* patch */ void addAll(Map<K, V> other) { | 220 /* patch */ void addAll(Map<K, V> other) { |
| 221 other.forEach((K key, V value) { | 221 other.forEach((K key, V value) { |
| 222 int offset = _hashTable._put(key); | 222 int offset = _hashTable._put(key); |
| 223 _hashTable._setValue(offset, value); | 223 _hashTable._setValue(offset, value); |
| 224 _hashTable._checkCapacity(); | 224 _hashTable._checkCapacity(); |
| 225 }); | 225 }); |
| 226 } | 226 } |
| 227 | 227 |
| 228 /* patch */ V operator [](K key) { | 228 /* patch */ V operator [](Object key) { |
| 229 int offset = _hashTable._get(key); | 229 int offset = _hashTable._get(key); |
| 230 if (offset >= 0) return _hashTable._value(offset); | 230 if (offset >= 0) return _hashTable._value(offset); |
| 231 return null; | 231 return null; |
| 232 } | 232 } |
| 233 | 233 |
| 234 /* patch */ void operator []=(K key, V value) { | 234 /* patch */ void operator []=(K key, V value) { |
| 235 int offset = _hashTable._put(key); | 235 int offset = _hashTable._put(key); |
| 236 _hashTable._setValue(offset, value); | 236 _hashTable._setValue(offset, value); |
| 237 _hashTable._checkCapacity(); | 237 _hashTable._checkCapacity(); |
| 238 } | 238 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 260 } else { | 260 } else { |
| 261 // The table might have changed, so we can't trust [offset] any more. | 261 // The table might have changed, so we can't trust [offset] any more. |
| 262 // Do another lookup before setting the value. | 262 // Do another lookup before setting the value. |
| 263 offset = _hashTable._put(key); | 263 offset = _hashTable._put(key); |
| 264 _hashTable._setValue(offset, value); | 264 _hashTable._setValue(offset, value); |
| 265 _hashTable._checkCapacity(); | 265 _hashTable._checkCapacity(); |
| 266 } | 266 } |
| 267 return value; | 267 return value; |
| 268 } | 268 } |
| 269 | 269 |
| 270 /* patch */ V remove(K key) { | 270 /* patch */ V remove(Object key) { |
| 271 int offset = _hashTable._remove(key); | 271 int offset = _hashTable._remove(key); |
| 272 if (offset < 0) return null; | 272 if (offset < 0) return null; |
| 273 Object oldValue = _hashTable._value(offset); | 273 Object oldValue = _hashTable._value(offset); |
| 274 _hashTable._setValue(offset, null); | 274 _hashTable._setValue(offset, null); |
| 275 _hashTable._checkCapacity(); | 275 _hashTable._checkCapacity(); |
| 276 return oldValue; | 276 return oldValue; |
| 277 } | 277 } |
| 278 | 278 |
| 279 /* patch */ void clear() { | 279 /* patch */ void clear() { |
| 280 _hashTable._clear(); | 280 _hashTable._clear(); |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 */ | 629 */ |
| 630 void _copyEntry(List fromTable, int fromOffset, int toOffset) {} | 630 void _copyEntry(List fromTable, int fromOffset, int toOffset) {} |
| 631 | 631 |
| 632 // The following three methods are for simple get/set/remove operations. | 632 // The following three methods are for simple get/set/remove operations. |
| 633 // They only affect the key of an entry. The remaining fields must be | 633 // They only affect the key of an entry. The remaining fields must be |
| 634 // filled by the caller. | 634 // filled by the caller. |
| 635 | 635 |
| 636 /** | 636 /** |
| 637 * Returns the offset of a key in [_table], or negative if it's not there. | 637 * Returns the offset of a key in [_table], or negative if it's not there. |
| 638 */ | 638 */ |
| 639 int _get(K key) { | 639 int _get(Object key) { |
| 640 return _probeForLookup(_hashCodeOf(key), key); | 640 return _probeForLookup(_hashCodeOf(key), key); |
| 641 } | 641 } |
| 642 | 642 |
| 643 /** | 643 /** |
| 644 * Puts the key into the table and returns its offset into [_table]. | 644 * Puts the key into the table and returns its offset into [_table]. |
| 645 * | 645 * |
| 646 * If [_entrySize] is greater than 1, the caller should fill the | 646 * If [_entrySize] is greater than 1, the caller should fill the |
| 647 * remaining fields. | 647 * remaining fields. |
| 648 * | 648 * |
| 649 * Remember to call [_checkCapacity] after using this method. | 649 * Remember to call [_checkCapacity] after using this method. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 663 return offset; | 663 return offset; |
| 664 } | 664 } |
| 665 | 665 |
| 666 /** | 666 /** |
| 667 * Removes a key from the table and returns its offset into [_table]. | 667 * Removes a key from the table and returns its offset into [_table]. |
| 668 * | 668 * |
| 669 * Returns null if the key was not in the table. | 669 * Returns null if the key was not in the table. |
| 670 * If [_entrySize] is greater than 1, the caller should clean up the | 670 * If [_entrySize] is greater than 1, the caller should clean up the |
| 671 * remaining fields. | 671 * remaining fields. |
| 672 */ | 672 */ |
| 673 int _remove(K key) { | 673 int _remove(Object key) { |
| 674 int offset = _probeForLookup(_hashCodeOf(key), key); | 674 int offset = _probeForLookup(_hashCodeOf(key), key); |
| 675 if (offset >= 0) { | 675 if (offset >= 0) { |
| 676 _deleteEntry(offset); | 676 _deleteEntry(offset); |
| 677 } | 677 } |
| 678 return offset; | 678 return offset; |
| 679 } | 679 } |
| 680 | 680 |
| 681 /** Clears the table completely, leaving it empty. */ | 681 /** Clears the table completely, leaving it empty. */ |
| 682 void _clear() { | 682 void _clear() { |
| 683 if (_elementCount == 0) return; | 683 if (_elementCount == 0) return; |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 993 | 993 |
| 994 _LinkedHashMapTable() : super(_INITIAL_CAPACITY); | 994 _LinkedHashMapTable() : super(_INITIAL_CAPACITY); |
| 995 | 995 |
| 996 V _value(int offset) => _table[offset + _VALUE_INDEX]; | 996 V _value(int offset) => _table[offset + _VALUE_INDEX]; |
| 997 void _setValue(int offset, V value) { _table[offset + _VALUE_INDEX] = value; } | 997 void _setValue(int offset, V value) { _table[offset + _VALUE_INDEX] = value; } |
| 998 | 998 |
| 999 _copyEntry(List oldTable, int fromOffset, int toOffset) { | 999 _copyEntry(List oldTable, int fromOffset, int toOffset) { |
| 1000 _table[toOffset + _VALUE_INDEX] = oldTable[fromOffset + _VALUE_INDEX]; | 1000 _table[toOffset + _VALUE_INDEX] = oldTable[fromOffset + _VALUE_INDEX]; |
| 1001 } | 1001 } |
| 1002 } | 1002 } |
| OLD | NEW |