mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:19:49 +00:00
Made HashMap.update faster by reducing it to one lookup.
fixes https://github.com/dart-lang/sdk/issues/48866 Test=ci and golem Change-Id: Ia56bd5b5de83dc8f7263eeda27e7abd3af42851e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/242120 Reviewed-by: Siva Annamalai <asiva@google.com> Commit-Queue: Siva Annamalai <asiva@google.com> Reviewed-by: Lasse Nielsen <lrn@google.com>
This commit is contained in:
parent
ad4126bba4
commit
904303f8a1
|
@ -239,6 +239,28 @@ class _HashMap<K, V> extends MapBase<K, V> implements HashMap<K, V> {
|
|||
_buckets = newBuckets;
|
||||
}
|
||||
|
||||
@override
|
||||
V update(K key, V update(V value), {V Function()? ifAbsent}) {
|
||||
final hashCode = key.hashCode;
|
||||
final buckets = _buckets;
|
||||
final length = buckets.length;
|
||||
final index = hashCode & (length - 1);
|
||||
var entry = buckets[index];
|
||||
while (entry != null) {
|
||||
if (hashCode == entry.hashCode && entry.key == key) {
|
||||
return entry.value = update(entry.value);
|
||||
}
|
||||
entry = entry.next;
|
||||
}
|
||||
if (ifAbsent != null) {
|
||||
V newValue = ifAbsent();
|
||||
_addEntry(buckets, index, length, key, newValue, hashCode);
|
||||
return newValue;
|
||||
} else {
|
||||
throw ArgumentError.value(key, "key", "Key not in map.");
|
||||
}
|
||||
}
|
||||
|
||||
Set<K> _newKeySet() => new _HashSet<K>();
|
||||
}
|
||||
|
||||
|
@ -429,6 +451,28 @@ class _IdentityHashMap<K, V> extends _HashMap<K, V> {
|
|||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
V update(K key, V update(V value), {V Function()? ifAbsent}) {
|
||||
final hashCode = identityHashCode(key);
|
||||
final buckets = _buckets;
|
||||
final length = buckets.length;
|
||||
final index = hashCode & (length - 1);
|
||||
var entry = buckets[index];
|
||||
while (entry != null) {
|
||||
if (hashCode == entry.hashCode && identical(entry.key, key)) {
|
||||
return entry.value = update(entry.value);
|
||||
}
|
||||
entry = entry.next;
|
||||
}
|
||||
if (ifAbsent != null) {
|
||||
V newValue = ifAbsent();
|
||||
_addEntry(buckets, index, length, key, newValue, hashCode);
|
||||
return newValue;
|
||||
} else {
|
||||
throw ArgumentError.value(key, "key", "Key not in map.");
|
||||
}
|
||||
}
|
||||
|
||||
Set<K> _newKeySet() => new _IdentityHashSet<K>();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue