Improve performance by not checking all indexed elements
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Trigger Docs Build (push) Blocked by required conditions Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[early-access:true toolchain:true version:24], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[early-access:true toolchain:true version:24], map[id:windows-latest name:Windows]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:windows-latest name:Windows]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:21], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:21], map[id:windows-latest name:Windows]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:22], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:22], map[id:windows-latest name:Windows]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:23], map[id:${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} name:Linux]) (push) Waiting to run Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:23], map[id:windows-latest name:Windows]) (push) Waiting to run Details
Run System Tests / Java ${{ matrix.java.version}} (map[toolchain:false version:17]) (push) Waiting to run Details
Run System Tests / Java ${{ matrix.java.version}} (map[toolchain:true version:21]) (push) Waiting to run Details

Update `IndexedElementsBinder` so that bind operations are faster at
the expense of not checking that all elements have been bound. The
updated code now uses a window of 10 elements and assumes that if
no elements are missing from that window then exhaustive checking is
not required.

Closes gh-44867
This commit is contained in:
Phillip Webb 2025-03-24 20:55:44 -07:00
parent 9c25b69c06
commit 93113a415f
1 changed files with 33 additions and 6 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -43,7 +43,13 @@ import org.springframework.util.MultiValueMap;
*/
abstract class IndexedElementsBinder<T> extends AggregateBinder<T> {
private static final String INDEX_ZERO = "[0]";
private static final String[] INDEXES;
static {
INDEXES = new String[10];
for (int i = 0; i < INDEXES.length; i++) {
INDEXES[i] = "[" + i + "]";
}
}
IndexedElementsBinder(Context context) {
super(context);
@ -100,15 +106,36 @@ abstract class IndexedElementsBinder<T> extends AggregateBinder<T> {
private void bindIndexed(ConfigurationPropertySource source, ConfigurationPropertyName root,
AggregateElementBinder elementBinder, IndexedCollectionSupplier collection, ResolvableType elementType) {
MultiValueMap<String, ConfigurationPropertyName> knownIndexedChildren = getKnownIndexedChildren(source, root);
int firstUnboundIndex = 0;
boolean hasBindingGap = false;
for (int i = 0; i < Integer.MAX_VALUE; i++) {
ConfigurationPropertyName name = root.append((i != 0) ? "[" + i + "]" : INDEX_ZERO);
ConfigurationPropertyName name = appendIndex(root, i);
Object value = elementBinder.bind(name, Bindable.of(elementType), source);
if (value == null) {
if (value != null) {
collection.get().add(value);
hasBindingGap = hasBindingGap || firstUnboundIndex > 0;
continue;
}
firstUnboundIndex = (firstUnboundIndex <= 0) ? i : firstUnboundIndex;
if (i - firstUnboundIndex > 10) {
break;
}
}
if (hasBindingGap) {
assertNoUnboundChildren(source, root, firstUnboundIndex);
}
}
private ConfigurationPropertyName appendIndex(ConfigurationPropertyName root, int i) {
return root.append((i < INDEXES.length) ? INDEXES[i] : "[" + i + "]");
}
private void assertNoUnboundChildren(ConfigurationPropertySource source, ConfigurationPropertyName root,
int firstUnboundIndex) {
MultiValueMap<String, ConfigurationPropertyName> knownIndexedChildren = getKnownIndexedChildren(source, root);
for (int i = 0; i < firstUnboundIndex; i++) {
ConfigurationPropertyName name = appendIndex(root, i);
knownIndexedChildren.remove(name.getLastElement(Form.UNIFORM));
collection.get().add(value);
}
assertNoUnboundChildren(source, knownIndexedChildren);
}