[prev in list] [next in list] [prev in thread] [next in thread] 

List:       httpcomponents-commits
Subject:    [httpcomponents-client] branch master updated: Optimize ExecSupport.getNextExchangeId() (#352)
From:       olegk () apache ! org
Date:       2022-02-26 11:45:28
Message-ID: 164587592820.5172.12084888026723899036 () gitbox ! apache ! org
[Download RAW message or body]

This is an automated email from the ASF dual-hosted git repository.

olegk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-client.git


The following commit(s) were added to refs/heads/master by this push:
     new 04aeaa5  Optimize ExecSupport.getNextExchangeId() (#352)
04aeaa5 is described below

commit 04aeaa5bcdd63d6a21ea8ce64e27066da689683c
Author: David Schlosnagle <schlosna@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 426a851..953be5f 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;
@@ -42,6 +41,7 @@ import org.apache.hc.client5.http.config.ConnectionConfig;
 import org.apache.hc.client5.http.config.TlsConfig;
 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;
@@ -605,7 +605,7 @@ public class PoolingHttpClientConnectionManager
                 .build());
     }
 
-    private static final AtomicLong COUNT = new AtomicLong(0);
+    private static final PrefixedIncrementingId INCREMENTING_ID = new \
PrefixedIncrementingId("ep-");  
     class InternalConnectionEndpoint extends ConnectionEndpoint implements \
Identifiable {  
@@ -615,7 +615,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 261b8f4..b40acb1 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;
@@ -44,6 +43,7 @@ import org.apache.hc.client5.http.config.ConnectionConfig;
 import org.apache.hc.client5.http.config.TlsConfig;
 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;
@@ -640,7 +640,7 @@ public class PoolingAsyncClientConnectionManager implements \
                AsyncClientConnectio
                 .build());
     }
 
-    private static final AtomicLong COUNT = new AtomicLong(0);
+    private static final PrefixedIncrementingId INCREMENTING_ID = new \
PrefixedIncrementingId("ep-");  
     class InternalConnectionEndpoint extends AsyncConnectionEndpoint implements \
Identifiable {  
@@ -649,7 +649,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..8ab023f 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.jupiter.api.Assertions;
+import org.junit.jupiter.api.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++) {
+            Assertions.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 56%
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..1a66963 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.jupiter.api.Assertions;
+import org.junit.jupiter.api.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
+    void testGetNextId() {
+        final PrefixedIncrementingId testId = new PrefixedIncrementingId("test-");
+        Assertions.assertEquals(String.format("test-%010d", 1), testId.getNextId());
+        Assertions.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-");
+        Assertions.assertEquals(String.format("ex-%010d", 0), \
exchangeId.createId(0)); +        for (long i = 1; i <= 100_000_000L; i *= 10) {
+            Assertions.assertEquals(String.format("ex-%010d", i - 1), \
exchangeId.createId(i - 1)); +            \
Assertions.assertEquals(String.format("ex-%010d", i), exchangeId.createId(i)); +      \
Assertions.assertEquals(String.format("ex-%010d", i + 1), exchangeId.createId(i + \
1)); +        }
     }
 
 }


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic