Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 // TODO(ahe): Remove this file and use the shared one. | |
| 6 | |
| 5 // Hash map implementation with open addressing and quadratic probing. | 7 // Hash map implementation with open addressing and quadratic probing. |
| 6 class HashMapImplementation<K extends Hashable, V> implements HashMap<K, V> { | 8 class HashMapImplementation<K extends Hashable, V> implements HashMap<K, V> { |
| 7 | 9 |
| 8 // The [_keys] list contains the keys inserted in the map. | 10 // The [_keys] list contains the keys inserted in the map. |
| 9 // The [_keys] list must be a raw list because it | 11 // The [_keys] list must be a raw list because it |
| 10 // will contain both elements of type K, and the [_DELETED_KEY] of type | 12 // will contain both elements of type K, and the [_DELETED_KEY] of type |
| 11 // [_DeletedKeySentinel]. | 13 // [_DeletedKeySentinel]. |
| 12 // The alternative of declaring the [_keys] list as of type Object | 14 // The alternative of declaring the [_keys] list as of type Object |
| 13 // does not work, because the HashSetIterator constructor would fail: | 15 // does not work, because the HashSetIterator constructor would fail: |
| 14 // HashSetIterator(HashSet<E> set) | 16 // HashSetIterator(HashSet<E> set) |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 149 int capacity = _keys.length; | 151 int capacity = _keys.length; |
| 150 _loadLimit = _computeLoadLimit(newCapacity); | 152 _loadLimit = _computeLoadLimit(newCapacity); |
| 151 List oldKeys = _keys; | 153 List oldKeys = _keys; |
| 152 List<V> oldValues = _values; | 154 List<V> oldValues = _values; |
| 153 _keys = new List(newCapacity); | 155 _keys = new List(newCapacity); |
| 154 _values = new List<V>(newCapacity); | 156 _values = new List<V>(newCapacity); |
| 155 for (int i = 0; i < capacity; i++) { | 157 for (int i = 0; i < capacity; i++) { |
| 156 // [key] can be either of type [K] or [_DeletedKeySentinel]. | 158 // [key] can be either of type [K] or [_DeletedKeySentinel]. |
| 157 Object key = oldKeys[i]; | 159 Object key = oldKeys[i]; |
| 158 // If there is no key, we don't need to deal with the current slot. | 160 // If there is no key, we don't need to deal with the current slot. |
| 159 if (key === null || key === _DELETED_KEY) { | 161 if (key !== null && key !== _DELETED_KEY) { |
| 160 continue; | 162 V value = oldValues[i]; |
| 163 // Insert the {key, value} pair in their new slot. | |
| 164 int newIndex = _probeForAdding(key); | |
| 165 _keys[newIndex] = key; | |
| 166 _values[newIndex] = value; | |
| 161 } | 167 } |
| 162 V value = oldValues[i]; | |
| 163 // Insert the {key, value} pair in their new slot. | |
| 164 int newIndex = _probeForAdding(key); | |
| 165 _keys[newIndex] = key; | |
| 166 _values[newIndex] = value; | |
| 167 } | 168 } |
| 168 _numberOfDeleted = 0; | 169 _numberOfDeleted = 0; |
| 169 } | 170 } |
| 170 | 171 |
| 171 void clear() { | 172 void clear() { |
| 172 _numberOfEntries = 0; | 173 _numberOfEntries = 0; |
| 173 _numberOfDeleted = 0; | 174 _numberOfDeleted = 0; |
| 174 int length = _keys.length; | 175 int length = _keys.length; |
| 175 for (int i = 0; i < length; i++) { | 176 for (int i = 0; i < length; i++) { |
| 176 _keys[i] = null; | 177 _keys[i] = null; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 300 return _backingMap.containsKey(value); | 301 return _backingMap.containsKey(value); |
| 301 } | 302 } |
| 302 | 303 |
| 303 bool remove(E value) { | 304 bool remove(E value) { |
| 304 if (!_backingMap.containsKey(value)) return false; | 305 if (!_backingMap.containsKey(value)) return false; |
| 305 _backingMap.remove(value); | 306 _backingMap.remove(value); |
| 306 return true; | 307 return true; |
| 307 } | 308 } |
| 308 | 309 |
| 309 void addAll(Collection<E> collection) { | 310 void addAll(Collection<E> collection) { |
| 311 var self = this; | |
|
ahe
2012/02/29 12:37:21
I should be able to remove all the "self" referenc
| |
| 310 collection.forEach(void _(E value) { | 312 collection.forEach(void _(E value) { |
| 311 add(value); | 313 self.add(value); |
| 312 }); | 314 }); |
| 313 } | 315 } |
| 314 | 316 |
| 315 Set<E> intersection(Collection<E> collection) { | 317 Set<E> intersection(Collection<E> collection) { |
| 318 var self = this; | |
| 316 Set<E> result = new Set<E>(); | 319 Set<E> result = new Set<E>(); |
| 317 collection.forEach(void _(E value) { | 320 collection.forEach(void _(E value) { |
| 318 if (contains(value)) result.add(value); | 321 if (self.contains(value)) result.add(value); |
| 319 }); | 322 }); |
| 320 return result; | 323 return result; |
| 321 } | 324 } |
| 322 | 325 |
| 323 bool isSubsetOf(Collection<E> other) { | 326 bool isSubsetOf(Collection<E> other) { |
| 324 return new Set<E>.from(other).containsAll(this); | 327 return new Set.from(other).containsAll(this); |
| 325 } | 328 } |
| 326 | 329 |
| 327 void removeAll(Collection<E> collection) { | 330 void removeAll(Collection<E> collection) { |
| 331 var self = this; | |
| 328 collection.forEach(void _(E value) { | 332 collection.forEach(void _(E value) { |
| 329 remove(value); | 333 self.remove(value); |
| 330 }); | 334 }); |
| 331 } | 335 } |
| 332 | 336 |
| 333 bool containsAll(Collection<E> collection) { | 337 bool containsAll(Collection<E> collection) { |
| 338 var self = this; | |
| 334 return collection.every(bool _(E value) { | 339 return collection.every(bool _(E value) { |
| 335 return contains(value); | 340 return self.contains(value); |
| 336 }); | 341 }); |
| 337 } | 342 } |
| 338 | 343 |
| 339 void forEach(void f(E element)) { | 344 void forEach(void f(E element)) { |
| 340 _backingMap.forEach(void _(E key, E value) { | 345 _backingMap.forEach(void _(E key, E value) { |
| 341 f(key); | 346 f(key); |
| 342 }); | 347 }); |
| 343 } | 348 } |
| 344 | 349 |
| 345 Set map(f(E element)) { | 350 Set map(f(E element)) { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 440 | 445 |
| 441 /** | 446 /** |
| 442 * A singleton sentinel used to represent when a key is deleted from the map. | 447 * A singleton sentinel used to represent when a key is deleted from the map. |
| 443 * We can't use [: const Object() :] as a sentinel because it would end up | 448 * We can't use [: const Object() :] as a sentinel because it would end up |
| 444 * canonicalized and then we cannot distinguish the deleted key from the | 449 * canonicalized and then we cannot distinguish the deleted key from the |
| 445 * canonicalized [: Object() :]. | 450 * canonicalized [: Object() :]. |
| 446 */ | 451 */ |
| 447 class _DeletedKeySentinel { | 452 class _DeletedKeySentinel { |
| 448 const _DeletedKeySentinel(); | 453 const _DeletedKeySentinel(); |
| 449 } | 454 } |
| OLD | NEW |