From dd8ace8d685bd0cf33d3299b20eb074b44cfd3c2 Mon Sep 17 00:00:00 2001 From: aalsanie Date: Fri, 6 Feb 2026 10:00:39 +0300 Subject: [PATCH 1/2] Optimize ContextPairs nested name splitting See gh-48999 Signed-off-by: aalsanie --- .../boot/logging/structured/ContextPairs.java | 35 ++++++++++++++++--- .../logging/structured/ContextPairsTests.java | 13 +++++++ 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/ContextPairs.java b/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/ContextPairs.java index 75c268d7201..69fd6628e37 100644 --- a/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/ContextPairs.java +++ b/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/ContextPairs.java @@ -193,24 +193,49 @@ public class ContextPairs { LinkedHashMap result = new LinkedHashMap<>(); this.addedPairs.forEach((addedPair) -> { addedPair.accept(item, joining((name, value) -> { - List nameParts = List.of(name.split("\\.")); Map destination = result; - for (int i = 0; i < nameParts.size() - 1; i++) { - Object existing = destination.computeIfAbsent(nameParts.get(i), (key) -> new LinkedHashMap<>()); + + int end = trimTrailingDelimiters(name); + if (end == 0) { + return; + } + + int start = 0; + while (true) { + int dot = name.indexOf('.', start); + if (dot == -1 || dot >= end) { + break; + } + + String part = name.substring(start, dot); + + Object existing = destination.computeIfAbsent(part, (key) -> new LinkedHashMap<>()); if (!(existing instanceof Map)) { - String common = String.join(".", nameParts.subList(0, i + 1)); + String common = name.substring(0, dot); throw new IllegalStateException( "Duplicate nested pairs added under '%s'".formatted(common)); } + destination = (Map) existing; + start = dot + 1; } - Object previous = destination.put(nameParts.get(nameParts.size() - 1), value); + + String leaf = name.substring(start, end); + Object previous = destination.put(leaf, value); Assert.state(previous == null, () -> "Duplicate nested pairs added under '%s'".formatted(name)); })); }); result.forEach(pairs); } + private int trimTrailingDelimiters(String name) { + int end = name.length(); + while (end > 0 && name.charAt(end - 1) == '.') { + end--; + } + return end; + } + private BiConsumer joining(BiConsumer pairs) { return (name, value) -> { name = this.joiner.join(ContextPairs.this.prefix, (name != null) ? name : ""); diff --git a/core/spring-boot/src/test/java/org/springframework/boot/logging/structured/ContextPairsTests.java b/core/spring-boot/src/test/java/org/springframework/boot/logging/structured/ContextPairsTests.java index e0013d0a868..0b9b7973045 100644 --- a/core/spring-boot/src/test/java/org/springframework/boot/logging/structured/ContextPairsTests.java +++ b/core/spring-boot/src/test/java/org/springframework/boot/logging/structured/ContextPairsTests.java @@ -120,6 +120,19 @@ class ContextPairsTests { assertThat(actual).isEqualTo(expected); } + @Test + void nestedWhenNameEndsWithDelimiterDropsTrailingDelimiter() { + ContextPairs contextPairs = new ContextPairs(true, null); + Map map = new LinkedHashMap<>(); + map.put("a1.b1.", "A1B1"); + Map actual = apply(contextPairs.nested((pairs) -> pairs.addMapEntries((item) -> map))); + Map expected = new LinkedHashMap<>(); + Map a1 = new LinkedHashMap<>(); + expected.put("a1", a1); + a1.put("b1", "A1B1"); + assertThat(actual).isEqualTo(expected); + } + @Test void nestedWhenDuplicateInParentThrowsException() { ContextPairs contextPairs = new ContextPairs(true, null); From 0a5e7ec1356cf679c6b7afc7aef63bb8790075f3 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Sun, 8 Feb 2026 15:09:41 -0800 Subject: [PATCH 2/2] Polish "Optimize ContextPairs nested name splitting" See gh-48999 --- .../boot/logging/structured/ContextPairs.java | 52 +++++++------------ 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/ContextPairs.java b/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/ContextPairs.java index 69fd6628e37..d5aebb1c10f 100644 --- a/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/ContextPairs.java +++ b/core/spring-boot/src/main/java/org/springframework/boot/logging/structured/ContextPairs.java @@ -193,47 +193,35 @@ public class ContextPairs { LinkedHashMap result = new LinkedHashMap<>(); this.addedPairs.forEach((addedPair) -> { addedPair.accept(item, joining((name, value) -> { + StringBuilder part = new StringBuilder(name.length()); + int length = (!name.endsWith(".")) ? name.length() : name.length() - 1; Map destination = result; - - int end = trimTrailingDelimiters(name); - if (end == 0) { - return; - } - - int start = 0; - while (true) { - int dot = name.indexOf('.', start); - if (dot == -1 || dot >= end) { - break; + for (int i = 0; i < length; i++) { + char ch = name.charAt(i); + if (i == length - 1) { + part.append(ch); + Object previous = destination.put(part.toString(), value); + assertNotDuplicateNestedPairs(previous == null, name, length); } - - String part = name.substring(start, dot); - - Object existing = destination.computeIfAbsent(part, (key) -> new LinkedHashMap<>()); - if (!(existing instanceof Map)) { - String common = name.substring(0, dot); - throw new IllegalStateException( - "Duplicate nested pairs added under '%s'".formatted(common)); + else if (ch == '.') { + Object current = destination.computeIfAbsent(part.toString(), + (key) -> new LinkedHashMap<>()); + assertNotDuplicateNestedPairs(current instanceof Map, name, i); + destination = (Map) current; + part.setLength(0); + } + else { + part.append(ch); } - - destination = (Map) existing; - start = dot + 1; } - - String leaf = name.substring(start, end); - Object previous = destination.put(leaf, value); - Assert.state(previous == null, () -> "Duplicate nested pairs added under '%s'".formatted(name)); })); }); result.forEach(pairs); } - private int trimTrailingDelimiters(String name) { - int end = name.length(); - while (end > 0 && name.charAt(end - 1) == '.') { - end--; - } - return end; + private void assertNotDuplicateNestedPairs(boolean expression, String name, int index) { + Assert.state(expression, + () -> "Duplicate nested pairs added under '%s'".formatted(name.substring(0, index))); } private BiConsumer joining(BiConsumer pairs) {