You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2022/02/26 11:58:29 UTC
[httpcomponents-client] branch 5.1.x updated: Optimize ExecSupport.getNextExchangeId() (#352)
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a commit to branch 5.1.x
in repository https://gitbox.apache.org/repos/asf/httpcomponents-client.git
The following commit(s) were added to refs/heads/5.1.x by this push:
new df63087 Optimize ExecSupport.getNextExchangeId() (#352)
df63087 is described below
commit df630878ad863e8c202235c38ac78cbd8ede1059
Author: David Schlosnagle <sc...@gmail.com>
AuthorDate: Sat Feb 26 06:45:18 2022 -0500
Optimize ExecSupport.getNextExchangeId() (#352)
---
.../apache/hc/client5/http/impl/ExecSupport.java | 9 +-
.../client5/http/impl/PrefixedIncrementingId.java | 109 +++++++++++++++++++++
.../io/PoolingHttpClientConnectionManager.java | 6 +-
.../nio/PoolingAsyncClientConnectionManager.java | 6 +-
.../hc/client5/http/impl/ExecSupportTest.java} | 30 +++---
.../http/impl/PrefixedIncrementingIdTest.java} | 33 ++++---
6 files changed, 146 insertions(+), 47 deletions(-)
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ExecSupport.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ExecSupport.java
index 4d7c5f6..6d9513f 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ExecSupport.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ExecSupport.java
@@ -26,8 +26,6 @@
*/
package org.apache.hc.client5.http.impl;
-import java.util.concurrent.atomic.AtomicLong;
-
import org.apache.hc.core5.annotation.Internal;
/**
@@ -38,14 +36,13 @@ import org.apache.hc.core5.annotation.Internal;
@Internal
public final class ExecSupport {
- private static final AtomicLong COUNT = new AtomicLong(0);
+ private static final PrefixedIncrementingId INCREMENTING_ID = new PrefixedIncrementingId("ex-");
public static long getNextExecNumber() {
- return COUNT.incrementAndGet();
+ return INCREMENTING_ID.getNextNumber();
}
public static String getNextExchangeId() {
- return String.format("ex-%010d", COUNT.incrementAndGet());
+ return INCREMENTING_ID.getNextId();
}
-
}
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/PrefixedIncrementingId.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/PrefixedIncrementingId.java
new file mode 100644
index 0000000..49e1d2d
--- /dev/null
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/PrefixedIncrementingId.java
@@ -0,0 +1,109 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl;
+
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * A thread safe incrementing identifier.
+ *
+ * @since 5.1.4
+ */
+@Internal
+public final class PrefixedIncrementingId {
+
+ private final AtomicLong count = new AtomicLong(0);
+ private final String prefix0;
+ private final String prefix1;
+ private final String prefix2;
+ private final String prefix3;
+ private final String prefix4;
+ private final String prefix5;
+ private final String prefix6;
+ private final String prefix7;
+ private final String prefix8;
+ private final String prefix9;
+
+ /**
+ * Creates an incrementing identifier.
+ * @param prefix string prefix for generated IDs
+ */
+ public PrefixedIncrementingId(final String prefix) {
+ this.prefix0 = Args.notNull(prefix, "prefix");
+ this.prefix1 = prefix0 + '0';
+ this.prefix2 = prefix1 + '0';
+ this.prefix3 = prefix2 + '0';
+ this.prefix4 = prefix3 + '0';
+ this.prefix5 = prefix4 + '0';
+ this.prefix6 = prefix5 + '0';
+ this.prefix7 = prefix6 + '0';
+ this.prefix8 = prefix7 + '0';
+ this.prefix9 = prefix8 + '0';
+ }
+
+ public long getNextNumber() {
+ return count.incrementAndGet();
+ }
+
+ public String getNextId() {
+ return createId(count.incrementAndGet());
+ }
+
+ /**
+ * Create an ID from this instance's prefix and zero padded specified value.
+ *
+ * Hand rolled equivalent to `String.format("ex-%010d", value)` optimized to reduce
+ * allocation and CPU overhead.
+ */
+ String createId(final long value) {
+ final String longString = Long.toString(value);
+ switch (longString.length()) {
+ case 1:
+ return prefix9 + longString;
+ case 2:
+ return prefix8 + longString;
+ case 3:
+ return prefix7 + longString;
+ case 4:
+ return prefix6 + longString;
+ case 5:
+ return prefix5 + longString;
+ case 6:
+ return prefix4 + longString;
+ case 7:
+ return prefix3 + longString;
+ case 8:
+ return prefix2 + longString;
+ case 9:
+ return prefix1 + longString;
+ default:
+ return prefix0 + longString;
+ }
+ }
+}
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java
index ae90703..c47e476 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java
@@ -32,7 +32,6 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.hc.client5.http.DnsResolver;
@@ -40,6 +39,7 @@ import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.client5.http.SchemePortResolver;
import org.apache.hc.client5.http.impl.ConnPoolSupport;
import org.apache.hc.client5.http.impl.ConnectionShutdownException;
+import org.apache.hc.client5.http.impl.PrefixedIncrementingId;
import org.apache.hc.client5.http.io.ConnectionEndpoint;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.io.HttpClientConnectionOperator;
@@ -503,7 +503,7 @@ public class PoolingHttpClientConnectionManager
this.validateAfterInactivity = validateAfterInactivity;
}
- private static final AtomicLong COUNT = new AtomicLong(0);
+ private static final PrefixedIncrementingId INCREMENTING_ID = new PrefixedIncrementingId("ep-");
class InternalConnectionEndpoint extends ConnectionEndpoint implements Identifiable {
@@ -513,7 +513,7 @@ public class PoolingHttpClientConnectionManager
InternalConnectionEndpoint(
final PoolEntry<HttpRoute, ManagedHttpClientConnection> poolEntry) {
this.poolEntryRef = new AtomicReference<>(poolEntry);
- this.id = String.format("ep-%010d", COUNT.getAndIncrement());
+ this.id = INCREMENTING_ID.getNextId();
}
@Override
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java
index 32617d6..1a3b8c0 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java
@@ -34,7 +34,6 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.hc.client5.http.DnsResolver;
@@ -42,6 +41,7 @@ import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.client5.http.SchemePortResolver;
import org.apache.hc.client5.http.impl.ConnPoolSupport;
import org.apache.hc.client5.http.impl.ConnectionShutdownException;
+import org.apache.hc.client5.http.impl.PrefixedIncrementingId;
import org.apache.hc.client5.http.nio.AsyncClientConnectionManager;
import org.apache.hc.client5.http.nio.AsyncClientConnectionOperator;
import org.apache.hc.client5.http.nio.AsyncConnectionEndpoint;
@@ -517,7 +517,7 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
this.validateAfterInactivity = validateAfterInactivity;
}
- private static final AtomicLong COUNT = new AtomicLong(0);
+ private static final PrefixedIncrementingId INCREMENTING_ID = new PrefixedIncrementingId("ep-");
class InternalConnectionEndpoint extends AsyncConnectionEndpoint implements Identifiable {
@@ -526,7 +526,7 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
InternalConnectionEndpoint(final PoolEntry<HttpRoute, ManagedAsyncClientConnection> poolEntry) {
this.poolEntryRef = new AtomicReference<>(poolEntry);
- this.id = String.format("ep-%010d", COUNT.getAndIncrement());
+ this.id = INCREMENTING_ID.getNextId();
}
@Override
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ExecSupport.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/ExecSupportTest.java
similarity index 72%
copy from httpclient5/src/main/java/org/apache/hc/client5/http/impl/ExecSupport.java
copy to httpclient5/src/test/java/org/apache/hc/client5/http/impl/ExecSupportTest.java
index 4d7c5f6..daf9d1d 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ExecSupport.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/ExecSupportTest.java
@@ -26,26 +26,18 @@
*/
package org.apache.hc.client5.http.impl;
-import java.util.concurrent.atomic.AtomicLong;
+import org.junit.Assert;
+import org.junit.Test;
-import org.apache.hc.core5.annotation.Internal;
+public class ExecSupportTest {
-/**
- * Request execution support methods.
- *
- * @since 5.0
- */
-@Internal
-public final class ExecSupport {
-
- private static final AtomicLong COUNT = new AtomicLong(0);
-
- public static long getNextExecNumber() {
- return COUNT.incrementAndGet();
+ @Test
+ public void testGetNextExchangeId() {
+ final long base = ExecSupport.getNextExecNumber();
+ for (int i = 1; i <= 1_000_000; i++) {
+ Assert.assertEquals(
+ String.format("ex-%010d", i + base),
+ ExecSupport.getNextExchangeId());
+ }
}
-
- public static String getNextExchangeId() {
- return String.format("ex-%010d", COUNT.incrementAndGet());
- }
-
}
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ExecSupport.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/PrefixedIncrementingIdTest.java
similarity index 57%
copy from httpclient5/src/main/java/org/apache/hc/client5/http/impl/ExecSupport.java
copy to httpclient5/src/test/java/org/apache/hc/client5/http/impl/PrefixedIncrementingIdTest.java
index 4d7c5f6..5a72d55 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ExecSupport.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/PrefixedIncrementingIdTest.java
@@ -26,26 +26,27 @@
*/
package org.apache.hc.client5.http.impl;
-import java.util.concurrent.atomic.AtomicLong;
+import org.junit.Assert;
+import org.junit.Test;
-import org.apache.hc.core5.annotation.Internal;
+public class PrefixedIncrementingIdTest {
-/**
- * Request execution support methods.
- *
- * @since 5.0
- */
-@Internal
-public final class ExecSupport {
-
- private static final AtomicLong COUNT = new AtomicLong(0);
-
- public static long getNextExecNumber() {
- return COUNT.incrementAndGet();
+ @Test
+ public void testGetNextId() {
+ final PrefixedIncrementingId testId = new PrefixedIncrementingId("test-");
+ Assert.assertEquals(String.format("test-%010d", 1), testId.getNextId());
+ Assert.assertEquals(String.format("test-%010d", 2), testId.getNextId());
}
- public static String getNextExchangeId() {
- return String.format("ex-%010d", COUNT.incrementAndGet());
+ @Test
+ public void testCreateId() {
+ final PrefixedIncrementingId exchangeId = new PrefixedIncrementingId("ex-");
+ Assert.assertEquals(String.format("ex-%010d", 0), exchangeId.createId(0));
+ for (long i = 1; i <= 100_000_000L; i *= 10) {
+ Assert.assertEquals(String.format("ex-%010d", i - 1), exchangeId.createId(i - 1));
+ Assert.assertEquals(String.format("ex-%010d", i), exchangeId.createId(i));
+ Assert.assertEquals(String.format("ex-%010d", i + 1), exchangeId.createId(i + 1));
+ }
}
}