Skip to content

Commit

Permalink
Avoid creating an identical ImmutableMap when the input to `Dict#co…
Browse files Browse the repository at this point in the history
…pyOf` is already an `ImmutableMap`.

Also use `forEach` for iteration to avoid creating entry set views.

PiperOrigin-RevId: 544088895
Change-Id: Iac12fe7754b5c95f5939e4f2124935abc26d955d
  • Loading branch information
justinhorvitz authored and copybara-github committed Jun 28, 2023
1 parent ba5c740 commit 62afb4b
Showing 1 changed file with 20 additions and 16 deletions.
36 changes: 20 additions & 16 deletions src/main/java/net/starlark/java/eval/Dict.java
Original file line number Diff line number Diff line change
Expand Up @@ -441,31 +441,35 @@ public static <K, V> Dict<K, V> copyOf(@Nullable Mutability mu, Map<? extends K,
mu = Mutability.IMMUTABLE;
}

if (mu == Mutability.IMMUTABLE && m instanceof Dict && ((Dict) m).isImmutable()) {
@SuppressWarnings("unchecked")
Dict<K, V> dict = (Dict<K, V>) m; // safe
return dict;
}

if (mu == Mutability.IMMUTABLE) {
if (m.isEmpty()) {
return empty();
}

if (m instanceof ImmutableMap) {
m.forEach(
(k, v) -> {
Starlark.checkValid(k);
Starlark.checkValid(v);
});
@SuppressWarnings("unchecked")
var immutableMap = (ImmutableMap<K, V>) m;
return new Dict<>(immutableMap);
}

if (m instanceof Dict && ((Dict<?, ?>) m).isImmutable()) {
@SuppressWarnings("unchecked")
var dict = (Dict<K, V>) m;
return dict;
}

ImmutableMap.Builder<K, V> immutableMapBuilder =
ImmutableMap.builderWithExpectedSize(m.size());
for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
immutableMapBuilder.put(
Starlark.checkValid(e.getKey()), //
Starlark.checkValid(e.getValue()));
}
m.forEach((k, v) -> immutableMapBuilder.put(Starlark.checkValid(k), Starlark.checkValid(v)));
return new Dict<>(immutableMapBuilder.buildOrThrow());
} else {
LinkedHashMap<K, V> linkedHashMap = Maps.newLinkedHashMapWithExpectedSize(m.size());
for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
linkedHashMap.put(
Starlark.checkValid(e.getKey()), //
Starlark.checkValid(e.getValue()));
}
m.forEach((k, v) -> linkedHashMap.put(Starlark.checkValid(k), Starlark.checkValid(v)));
return new Dict<>(mu, linkedHashMap);
}
}
Expand Down

0 comments on commit 62afb4b

Please sign in to comment.