Skip to content

Commit

Permalink
Ensure correct initial capacity is used for the map (#2739)
Browse files Browse the repository at this point in the history
  • Loading branch information
violetagg committed Mar 22, 2023
1 parent e3c3f97 commit 10c2330
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 VMware, Inc. or its affiliates, All Rights Reserved.
* Copyright (c) 2022-2023 VMware, Inc. or its affiliates, All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,8 +19,7 @@
import java.util.function.Function;

/**
* It's a temporary workaround for Java 8 specific performance issue JDK-8161372
* and this class should be removed once the Java 8 support is dropped.
* This class contains temporary workarounds for Java 8 {@link Map} issues.
* <p><strong>Note:</strong> This utility class is for internal use only. It can be removed at any time.
*
* @author zimatars
Expand All @@ -29,6 +28,24 @@
public final class MapUtils {

/**
* This is a temporary workaround for Java 8 issue https://bugs.openjdk.org/browse/JDK-8186958. Fix is available
* in Java 19.
* <p>
* Calculate the initial capacity for the {@link Map} from the expected size and the default load factor
* for the {@link Map} (0.75).
*
* @param expectedSize the expected size
* @return the initial capacity for the {@link Map}
* @since 1.0.31
*/
public static int calculateInitialCapacity(int expectedSize) {
return (int) Math.ceil(expectedSize / 0.75);
}

/**
* This is a temporary workaround for Java 8 specific performance issue https://bugs.openjdk.org/browse/JDK-8161372.
* Fix is available in Java 9.
* <p>
* ConcurrentHashMap.computeIfAbsent(k,v) locks when k is present.
* Add pre-screen before locking inside computeIfAbsent.
* <p><strong>Note:</strong> This utility is not for a general purpose usage.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2021 VMware, Inc. or its affiliates, All Rights Reserved.
* Copyright (c) 2017-2023 VMware, Inc. or its affiliates, All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,6 +18,7 @@
import io.netty.channel.ChannelOption;
import reactor.core.publisher.Mono;
import reactor.netty.DisposableServer;
import reactor.netty.internal.util.MapUtils;

import java.net.InetSocketAddress;
import java.util.Collections;
Expand All @@ -37,7 +38,7 @@ final class TcpServerBind extends TcpServer {
final TcpServerConfig config;

TcpServerBind() {
Map<ChannelOption<?>, Boolean> childOptions = new HashMap<>(2);
Map<ChannelOption<?>, Boolean> childOptions = new HashMap<>(MapUtils.calculateInitialCapacity(2));
childOptions.put(ChannelOption.AUTO_READ, false);
childOptions.put(ChannelOption.TCP_NODELAY, true);
this.config = new TcpServerConfig(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ public void disposeNow(Duration timeout) {
Mono<Void> terminateSignals = Mono.empty();
if (config.channelGroup != null && config.channelGroup.size() > 0) {
HashMap<Channel, List<Mono<Void>>> channelsToMono =
new HashMap<>((int) Math.ceil(config.channelGroup.size() / 0.75));
new HashMap<>(MapUtils.calculateInitialCapacity(config.channelGroup.size()));
// Wait for the running requests to finish
for (Channel channel : config.channelGroup) {
Channel parent = channel.parent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import reactor.netty.NettyPipeline;
import reactor.netty.channel.ChannelMetricsRecorder;
import reactor.netty.channel.ChannelOperations;
import reactor.netty.internal.util.MapUtils;
import reactor.netty.resources.LoopResources;
import reactor.util.Logger;
import reactor.util.Loggers;
Expand Down Expand Up @@ -351,7 +352,7 @@ protected static <K, V> Map<K, V> updateMap(Map<K, V> parentMap, Object key, @Nu
return value == null ? parentMap : Collections.singletonMap((K) key, (V) value);
}
else {
Map<K, V> attrs = new HashMap<>(parentMap.size() + 1);
Map<K, V> attrs = new HashMap<>(MapUtils.calculateInitialCapacity(parentMap.size() + 1));
attrs.putAll(parentMap);
if (value == null) {
attrs.remove(key);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2021 VMware, Inc. or its affiliates, All Rights Reserved.
* Copyright (c) 2011-2023 VMware, Inc. or its affiliates, All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -26,6 +26,7 @@

import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpVersion;
import reactor.netty.internal.util.MapUtils;
import reactor.util.annotation.Nullable;

import static java.util.Objects.requireNonNull;
Expand Down Expand Up @@ -344,7 +345,7 @@ public boolean matches(String uri) {
* @return the path parameters from the uri. Never {@code null}.
*/
final Map<String, String> match(String uri) {
Map<String, String> pathParameters = new HashMap<>(pathVariables.size());
Map<String, String> pathParameters = new HashMap<>(MapUtils.calculateInitialCapacity(pathVariables.size()));

Matcher m = matcher(uri);
if (m.matches()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2021 VMware, Inc. or its affiliates, All Rights Reserved.
* Copyright (c) 2017-2023 VMware, Inc. or its affiliates, All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,6 +19,7 @@
import io.netty.util.AttributeKey;
import reactor.core.publisher.Mono;
import reactor.netty.DisposableServer;
import reactor.netty.internal.util.MapUtils;
import reactor.netty.tcp.SslProvider;
import reactor.netty.tcp.TcpServerConfig;

Expand All @@ -41,7 +42,7 @@ final class HttpServerBind extends HttpServer {
final HttpServerConfig config;

HttpServerBind() {
Map<ChannelOption<?>, Boolean> childOptions = new HashMap<>(2);
Map<ChannelOption<?>, Boolean> childOptions = new HashMap<>(MapUtils.calculateInitialCapacity(2));
childOptions.put(ChannelOption.AUTO_READ, false);
childOptions.put(ChannelOption.TCP_NODELAY, true);
this.config = new HttpServerConfig(
Expand Down

0 comments on commit 10c2330

Please sign in to comment.