Merge pull request #48999 from aalsanie

* pr/48999:
  Polish "Optimize ContextPairs nested name splitting"
  Optimize ContextPairs nested name splitting

Closes gh-48999
This commit is contained in:
Phillip Webb
2026-02-08 15:39:16 -08:00
2 changed files with 36 additions and 10 deletions
@@ -193,24 +193,37 @@ public class ContextPairs {
LinkedHashMap<String, Object> result = new LinkedHashMap<>();
this.addedPairs.forEach((addedPair) -> {
addedPair.accept(item, joining((name, value) -> {
List<String> nameParts = List.of(name.split("\\."));
StringBuilder part = new StringBuilder(name.length());
int length = (!name.endsWith(".")) ? name.length() : name.length() - 1;
Map<String, Object> destination = result;
for (int i = 0; i < nameParts.size() - 1; i++) {
Object existing = destination.computeIfAbsent(nameParts.get(i), (key) -> new LinkedHashMap<>());
if (!(existing instanceof Map)) {
String common = String.join(".", nameParts.subList(0, i + 1));
throw new IllegalStateException(
"Duplicate nested pairs added under '%s'".formatted(common));
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);
}
else if (ch == '.') {
Object current = destination.computeIfAbsent(part.toString(),
(key) -> new LinkedHashMap<>());
assertNotDuplicateNestedPairs(current instanceof Map, name, i);
destination = (Map<String, Object>) current;
part.setLength(0);
}
else {
part.append(ch);
}
destination = (Map<String, Object>) existing;
}
Object previous = destination.put(nameParts.get(nameParts.size() - 1), value);
Assert.state(previous == null, () -> "Duplicate nested pairs added under '%s'".formatted(name));
}));
});
result.forEach(pairs);
}
private void assertNotDuplicateNestedPairs(boolean expression, String name, int index) {
Assert.state(expression,
() -> "Duplicate nested pairs added under '%s'".formatted(name.substring(0, index)));
}
private <V> BiConsumer<String, V> joining(BiConsumer<String, V> pairs) {
return (name, value) -> {
name = this.joiner.join(ContextPairs.this.prefix, (name != null) ? name : "");
@@ -120,6 +120,19 @@ class ContextPairsTests {
assertThat(actual).isEqualTo(expected);
}
@Test
void nestedWhenNameEndsWithDelimiterDropsTrailingDelimiter() {
ContextPairs contextPairs = new ContextPairs(true, null);
Map<String, String> map = new LinkedHashMap<>();
map.put("a1.b1.", "A1B1");
Map<String, Object> actual = apply(contextPairs.nested((pairs) -> pairs.addMapEntries((item) -> map)));
Map<String, Object> expected = new LinkedHashMap<>();
Map<String, Object> a1 = new LinkedHashMap<>();
expected.put("a1", a1);
a1.put("b1", "A1B1");
assertThat(actual).isEqualTo(expected);
}
@Test
void nestedWhenDuplicateInParentThrowsException() {
ContextPairs contextPairs = new ContextPairs(true, null);