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

vy pushed a commit to branch recycler-api-3.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 13b507b790d396548094386d54e7c21308efa9bb
Author: Volkan Yazıcı <[email protected]>
AuthorDate: Wed Mar 29 13:55:10 2023 +0200

    Remove `ThreadLocal`s in `Strings`
---
 .../logging/log4j/message/MapMessageTest.java      | 16 ++-----
 .../org/apache/logging/log4j/util/StringsTest.java | 14 +-----
 .../org/apache/logging/log4j/util/Strings.java     | 45 ------------------
 .../logging/log4j/core/layout/GelfLayout.java      | 18 +++++--
 .../log4j/core/pattern/RepeatPatternConverter.java |  2 +-
 .../template/json/JsonTemplateLayoutTest.java      | 35 +++-----------
 .../layout/template/json/util/JsonWriterTest.java  | 55 ++++++++++------------
 .../json/JsonTemplateLayoutBenchmarkReport.java    |  8 ++--
 8 files changed, 55 insertions(+), 138 deletions(-)

diff --git 
a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
 
b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
index b4e67f3bc2..1b2bc8336e 100644
--- 
a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
+++ 
b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
@@ -19,17 +19,13 @@ package org.apache.logging.log4j.message;
 import java.math.BigDecimal;
 import java.sql.Date;
 import java.sql.Time;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
+import java.util.*;
 
 import org.apache.logging.log4j.util.StringBuilderFormattable;
-import org.apache.logging.log4j.util.Strings;
 import org.junit.jupiter.api.Test;
 
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 /**
  *
@@ -175,11 +171,7 @@ public class MapMessageTest {
     @Test
     public void testJsonFormatterMaxDepthConformance() {
         int depth = MapMessageJsonFormatter.MAX_DEPTH - 2;
-        String expectedJson = String
-                .format("{'key':%s1%s}",
-                        Strings.repeat("[", depth),
-                        Strings.repeat("]", depth))
-                .replace('\'', '"');
+        String expectedJson = String.format("{'key':%s1%s}", 
"[".repeat(depth), "]".repeat(depth)).replace('\'', '"');
         String actualJson = testJsonFormatterMaxDepth(depth);
         assertEquals(expectedJson, actualJson);
     }
diff --git 
a/log4j-api-test/src/test/java/org/apache/logging/log4j/util/StringsTest.java 
b/log4j-api-test/src/test/java/org/apache/logging/log4j/util/StringsTest.java
index 7c9695d3a8..e2c2f2b236 100644
--- 
a/log4j-api-test/src/test/java/org/apache/logging/log4j/util/StringsTest.java
+++ 
b/log4j-api-test/src/test/java/org/apache/logging/log4j/util/StringsTest.java
@@ -14,15 +14,14 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-
 package org.apache.logging.log4j.util;
 
-import org.junit.jupiter.api.Test;
-
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
 
+import org.junit.jupiter.api.Test;
+
 import static org.junit.jupiter.api.Assertions.*;
 
 public class StringsTest {
@@ -55,15 +54,6 @@ public class StringsTest {
         assertEquals(0, Strings.EMPTY.length());
     }
 
-    @Test
-    public void testConcat() {
-        assertEquals("ab", Strings.concat("a", "b"));
-        assertEquals("a", Strings.concat("a", ""));
-        assertEquals("a", Strings.concat("a", null));
-        assertEquals("b", Strings.concat("", "b"));
-        assertEquals("b", Strings.concat(null, "b"));
-    }
-
     @Test
     public void testJoin() {
         assertNull(Strings.join((Iterable<?>) null, '.'));
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/Strings.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/util/Strings.java
index 8a6fdfefb0..e88ac33fbd 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/Strings.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/Strings.java
@@ -29,8 +29,6 @@ import java.util.Optional;
 @InternalApi
 public final class Strings {
 
-    private static final ThreadLocal<StringBuilder> tempStr = 
ThreadLocal.withInitial(StringBuilder::new);
-
     /**
      * The empty string.
      */
@@ -313,47 +311,4 @@ public final class Strings {
         return string != null ? string.split(COMMA_DELIMITED_RE) : new 
String[0];
     }
 
-    /**
-     * Concatenates 2 Strings without allocation.
-     * @param str1 the first string.
-     * @param str2 the second string.
-     * @return the concatenated String.
-     */
-    public static String concat(final String str1, final String str2) {
-        if (isEmpty(str1)) {
-            return str2;
-        } else if (isEmpty(str2)) {
-            return str1;
-        }
-        final StringBuilder sb = tempStr.get();
-        try {
-            return sb.append(str1).append(str2).toString();
-        } finally {
-            sb.setLength(0);
-        }
-    }
-
-    /**
-     * Creates a new string repeating given {@code str} {@code count} times.
-     * @param str input string
-     * @param count the repetition count
-     * @return the new string
-     * @throws IllegalArgumentException if either {@code str} is null or 
{@code count} is negative
-     */
-    public static String repeat(final String str, final int count) {
-        Objects.requireNonNull(str, "str");
-        if (count < 0) {
-            throw new IllegalArgumentException("count");
-        }
-        final StringBuilder sb = tempStr.get();
-        try {
-            for (int index = 0; index < count; index++) {
-                sb.append(str);
-            }
-            return sb.toString();
-        } finally {
-            sb.setLength(0);
-        }
-    }
-
 }
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java
index 1ab7276cdc..e61206e562 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java
@@ -102,7 +102,7 @@ public final class GelfLayout extends AbstractStringLayout {
     private final PatternLayout layout;
     private final FieldWriter mdcWriter;
     private final FieldWriter mapWriter;
-    private final Recycler<StringBuilderWriter> stacktraceRecycler;
+    private final Recycler<StringBuilderWriter> stringBuilderWriterRecycler;
 
     public static class Builder<B extends Builder<B>> extends 
AbstractStringLayout.Builder<B>
         implements org.apache.logging.log4j.plugins.util.Builder<GelfLayout> {
@@ -460,7 +460,7 @@ public final class GelfLayout extends AbstractStringLayout {
         this.mdcWriter = new FieldWriter(mdcChecker, mdcPrefix);
         this.mapWriter = new FieldWriter(mapChecker, mapPrefix);
         this.layout = patternLayout;
-        stacktraceRecycler = config.getRecyclerFactory().create(
+        stringBuilderWriterRecycler = config.getRecyclerFactory().create(
                 () -> new StringBuilderWriter(MAX_STRING_BUILDER_SIZE),
                 writer -> {
                     final StringBuilder stringBuilder = writer.getBuilder();
@@ -626,12 +626,12 @@ public final class GelfLayout extends 
AbstractStringLayout {
                 }
             } else {
                 if (includeStacktrace) {
-                    final StringBuilderWriter writer = 
stacktraceRecycler.acquire();
+                    final StringBuilderWriter writer = 
stringBuilderWriterRecycler.acquire();
                     try {
                         formatThrowableTo(writer, event.getThrown());
                         JsonUtils.quoteAsString(writer.getBuilder(), builder);
                     } finally {
-                        stacktraceRecycler.release(writer);
+                        stringBuilderWriterRecycler.release(writer);
                     }
                 } else {
                     JsonUtils.quoteAsString(event.getThrown().toString(), 
builder);
@@ -684,7 +684,15 @@ public final class GelfLayout extends AbstractStringLayout 
{
             final String stringValue = String.valueOf(value);
             if (checker.check(key) && (Strings.isNotEmpty(stringValue) || 
!omitEmptyFields)) {
                 stringBuilder.append(QU);
-                JsonUtils.quoteAsString(Strings.concat(prefix, key), 
stringBuilder);
+                final StringBuilderWriter stringBuilderWriter = 
stringBuilderWriterRecycler.acquire();
+                final StringBuilder tmpStringBuilder = 
stringBuilderWriter.getBuilder();
+                try {
+                    tmpStringBuilder.append(prefix);
+                    tmpStringBuilder.append(key);
+                    JsonUtils.quoteAsString(tmpStringBuilder, stringBuilder);
+                } finally {
+                    stringBuilderWriterRecycler.release(stringBuilderWriter);
+                }
                 stringBuilder.append("\":\"");
                 JsonUtils.quoteAsString(toNullSafeString(stringValue), 
stringBuilder);
                 stringBuilder.append(QC);
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RepeatPatternConverter.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RepeatPatternConverter.java
index 59d6a8d8f2..744c17199e 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RepeatPatternConverter.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RepeatPatternConverter.java
@@ -58,7 +58,7 @@ public final class RepeatPatternConverter extends 
LogEventPatternConverter {
         String result = options[0];
         try {
             count = Integer.parseInt(options[1].trim());
-            result = Strings.repeat(options[0], count);
+            result = options[0].repeat(count);
         } catch (final Exception ex) {
             LOGGER.error("The repeat count is not an integer: {}", 
options[1].trim());
         }
diff --git 
a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutTest.java
 
b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutTest.java
index a1a53a4d4d..cba309490d 100644
--- 
a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutTest.java
+++ 
b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutTest.java
@@ -16,12 +16,7 @@
  */
 package org.apache.logging.log4j.layout.template.json;
 
-import java.io.ByteArrayOutputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
+import java.io.*;
 import java.math.BigDecimal;
 import java.net.ServerSocket;
 import java.net.Socket;
@@ -30,11 +25,7 @@ import java.nio.charset.Charset;
 import java.time.Instant;
 import java.time.temporal.ChronoField;
 import java.time.temporal.TemporalAccessor;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.TimeUnit;
@@ -56,24 +47,12 @@ import org.apache.logging.log4j.core.net.Severity;
 import org.apache.logging.log4j.core.test.AvailablePortFinder;
 import org.apache.logging.log4j.core.time.MutableInstant;
 import 
org.apache.logging.log4j.layout.template.json.JsonTemplateLayout.EventTemplateAdditionalField;
-import org.apache.logging.log4j.layout.template.json.resolver.EventResolver;
-import 
org.apache.logging.log4j.layout.template.json.resolver.EventResolverContext;
-import 
org.apache.logging.log4j.layout.template.json.resolver.EventResolverFactory;
-import org.apache.logging.log4j.layout.template.json.resolver.TemplateResolver;
-import 
org.apache.logging.log4j.layout.template.json.resolver.TemplateResolverConfig;
-import 
org.apache.logging.log4j.layout.template.json.resolver.TemplateResolverFactory;
+import org.apache.logging.log4j.layout.template.json.resolver.*;
 import org.apache.logging.log4j.layout.template.json.util.JsonWriter;
-import org.apache.logging.log4j.message.Message;
-import org.apache.logging.log4j.message.MessageFactory;
-import org.apache.logging.log4j.message.ObjectMessage;
-import org.apache.logging.log4j.message.ParameterizedMessageFactory;
-import org.apache.logging.log4j.message.ReusableMessageFactory;
-import org.apache.logging.log4j.message.SimpleMessage;
-import org.apache.logging.log4j.message.StringMapMessage;
+import org.apache.logging.log4j.message.*;
 import org.apache.logging.log4j.plugins.Namespace;
 import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.plugins.PluginFactory;
-import org.apache.logging.log4j.util.Strings;
 import org.junit.jupiter.api.Test;
 
 import com.fasterxml.jackson.databind.JsonNode;
@@ -721,7 +700,7 @@ class JsonTemplateLayoutTest {
 
         // Create the log event.
         final int maxStringLength = 30;
-        final String excessiveMessageString = Strings.repeat("m", 
maxStringLength) + 'M';
+        final String excessiveMessageString = "m".repeat(maxStringLength) + 
'M';
         final SimpleMessage message = new 
SimpleMessage(excessiveMessageString);
         final Throwable thrown = new RuntimeException();
         final LogEvent logEvent = Log4jLogEvent
@@ -734,8 +713,8 @@ class JsonTemplateLayoutTest {
 
         // Create the event template node with map values.
         final String messageKey = "message";
-        final String excessiveKey = Strings.repeat("k", maxStringLength) + 'K';
-        final String excessiveValue = Strings.repeat("v", maxStringLength) + 
'V';
+        final String excessiveKey = "k".repeat(maxStringLength) + 'K';
+        final String excessiveValue = "v".repeat(maxStringLength) + 'V';
         final String nullValueKey = "nullValueKey";
         final String eventTemplate = writeJson(asMap(
                 messageKey, asMap("$resolver", "message"),
diff --git 
a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/util/JsonWriterTest.java
 
b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/util/JsonWriterTest.java
index 5ce6e1f1d4..967ccbd77b 100644
--- 
a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/util/JsonWriterTest.java
+++ 
b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/util/JsonWriterTest.java
@@ -16,32 +16,25 @@
  */
 package org.apache.logging.log4j.layout.template.json.util;
 
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
 import org.apache.logging.log4j.core.impl.JdkMapAdapterStringMap;
 import org.apache.logging.log4j.layout.template.json.JacksonFixture;
 import org.apache.logging.log4j.util.IndexedReadOnlyStringMap;
 import org.apache.logging.log4j.util.SortedArrayStringMap;
 import org.apache.logging.log4j.util.StringBuilderFormattable;
 import org.apache.logging.log4j.util.StringMap;
-import org.apache.logging.log4j.util.Strings;
 import org.assertj.core.api.Assertions;
 import org.assertj.core.api.SoftAssertions;
 import org.junit.jupiter.api.Test;
 
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
 @SuppressWarnings("DoubleBraceInitialization")
 class JsonWriterTest {
 
@@ -89,7 +82,7 @@ class JsonWriterTest {
     @Test
     void test_close_after_excessive_write() {
         withLockedWriter(writer -> {
-            final String text = Strings.repeat("x", 
writer.getMaxStringLength());
+            final String text = "x".repeat(writer.getMaxStringLength());
             writer.writeString(text);
             writer.writeString(text);
             writer.close();
@@ -472,7 +465,7 @@ class JsonWriterTest {
     void test_writeString_emitter_excessive_string() {
         withLockedWriter(writer -> {
             final int maxStringLength = writer.getMaxStringLength();
-            final String excessiveString = Strings.repeat("x", 
maxStringLength) + 'y';
+            final String excessiveString = "x".repeat(maxStringLength) + 'y';
             final String expectedJson = '"' +
                     excessiveString.substring(0, maxStringLength) +
                     writer.getTruncatedStringSuffix() +
@@ -491,12 +484,12 @@ class JsonWriterTest {
             final int maxStringLength = writer.getMaxStringLength();
             @SuppressWarnings("StringBufferReplaceableByString")
             final String excessiveString = new StringBuilder()
-                    .append(Strings.repeat("x", maxStringLength - 1))
+                    .append("x".repeat(maxStringLength - 1))
                     .append(HI_SURROGATE)
                     .append(LO_SURROGATE)
                     .toString();
             final String expectedJson = "\"" +
-                    Strings.repeat("x", maxStringLength - 1) +
+                    "x".repeat(maxStringLength - 1) +
                     writer.getTruncatedStringSuffix() +
                     '"';
             final BiConsumer<StringBuilder, String> emitter = 
StringBuilder::append;
@@ -526,7 +519,7 @@ class JsonWriterTest {
     void test_writeString_formattable_excessive_string() {
         withLockedWriter(writer -> {
             final int maxStringLength = writer.getMaxStringLength();
-            final String excessiveString = Strings.repeat("x", 
maxStringLength) + 'y';
+            final String excessiveString = "x".repeat(maxStringLength) + 'y';
             final String expectedJson = '"' +
                     excessiveString.substring(0, maxStringLength) +
                     writer.getTruncatedStringSuffix() +
@@ -545,12 +538,12 @@ class JsonWriterTest {
             final int maxStringLength = writer.getMaxStringLength();
             @SuppressWarnings("StringBufferReplaceableByString")
             final String excessiveString = new StringBuilder()
-                    .append(Strings.repeat("x", maxStringLength - 1))
+                    .append("x".repeat(maxStringLength - 1))
                     .append(HI_SURROGATE)
                     .append(LO_SURROGATE)
                     .toString();
             final String expectedJson = "\"" +
-                    Strings.repeat("x", maxStringLength - 1) +
+                    "x".repeat(maxStringLength - 1) +
                     writer.getTruncatedStringSuffix() +
                     '"';
             final String actualJson = writer.use(() ->
@@ -612,9 +605,9 @@ class JsonWriterTest {
     @Test
     void test_writeString_excessive_seq() {
         withLockedWriter(writer -> {
-            final CharSequence seq = Strings.repeat("x", 
writer.getMaxStringLength()) + 'y';
+            final CharSequence seq = "x".repeat(writer.getMaxStringLength()) + 
'y';
             final String expectedJson = "\"" +
-                    Strings.repeat("x", writer.getMaxStringLength()) +
+                    "x".repeat(writer.getMaxStringLength()) +
                     writer.getTruncatedStringSuffix() +
                     '"';
             final String actualJson = writer.use(() -> 
writer.writeString(seq));
@@ -628,12 +621,12 @@ class JsonWriterTest {
             final int maxStringLength = writer.getMaxStringLength();
             @SuppressWarnings("StringBufferReplaceableByString")
             final CharSequence seq = new StringBuilder()
-                    .append(Strings.repeat("x", maxStringLength - 1))
+                    .append("x".repeat(maxStringLength - 1))
                     .append(HI_SURROGATE)
                     .append(LO_SURROGATE)
                     .toString();
             final String expectedJson = "\"" +
-                    Strings.repeat("x", maxStringLength - 1) +
+                    "x".repeat(maxStringLength - 1) +
                     writer.getTruncatedStringSuffix() +
                     '"';
             final String actualJson = writer.use(() -> 
writer.writeString(seq));
@@ -685,10 +678,10 @@ class JsonWriterTest {
     void test_writeString_excessive_buffer() {
         withLockedWriter(writer -> {
             final char[] buffer =
-                    (Strings.repeat("x", writer.getMaxStringLength()) + 'y')
+                    ("x".repeat(writer.getMaxStringLength()) + 'y')
                             .toCharArray();
             final String expectedJson = "\"" +
-                    Strings.repeat("x", writer.getMaxStringLength()) +
+                    "x".repeat(writer.getMaxStringLength()) +
                     writer.getTruncatedStringSuffix() +
                     '"';
             final String actualJson = writer.use(() -> 
writer.writeString(buffer));
@@ -702,13 +695,13 @@ class JsonWriterTest {
             final int maxStringLength = writer.getMaxStringLength();
             @SuppressWarnings("StringBufferReplaceableByString")
             final char[] buffer = new StringBuilder()
-                    .append(Strings.repeat("x", maxStringLength - 1))
+                    .append("x".repeat(maxStringLength - 1))
                     .append(HI_SURROGATE)
                     .append(LO_SURROGATE)
                     .toString()
                     .toCharArray();
             final String expectedJson = "\"" +
-                    Strings.repeat("x", maxStringLength - 1) +
+                    "x".repeat(maxStringLength - 1) +
                     writer.getTruncatedStringSuffix() +
                     '"';
             final String actualJson = writer.use(() -> 
writer.writeString(buffer));
diff --git 
a/log4j-perf/src/main/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutBenchmarkReport.java
 
b/log4j-perf/src/main/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutBenchmarkReport.java
index c971570646..771ebd2b87 100644
--- 
a/log4j-perf/src/main/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutBenchmarkReport.java
+++ 
b/log4j-perf/src/main/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutBenchmarkReport.java
@@ -16,9 +16,6 @@
  */
 package org.apache.logging.log4j.layout.template.json;
 
-import org.apache.logging.log4j.core.util.JsonReader;
-import org.apache.logging.log4j.util.Strings;
-
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -40,6 +37,9 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.stream.Collectors;
 
+import org.apache.logging.log4j.core.util.JsonReader;
+import org.apache.logging.log4j.util.Strings;
+
 /**
  * Utility class to summarize {@link JsonTemplateLayoutBenchmark} results in 
Asciidoctor.
  * <p>
@@ -361,7 +361,7 @@ public enum JsonTemplateLayoutBenchmarkReport {;
                 .toBigInteger()
                 .add(BigInteger.ONE)
                 .intValueExact();
-        final String opRateBar = Strings.repeat("▉", opRateBarLength);
+        final String opRateBar = "▉".repeat(opRateBarLength);
         final int opRatePercent = normalizedOpRate
                 .multiply(BigDecimal.valueOf(100))
                 .toBigInteger()

Reply via email to