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()
