Skip to content

Commit 72fe177

Browse files
committed
Speedup element equality checks in ConfigurationPropertyName
See spring-projectsgh-16401
1 parent ff1e507 commit 72fe177

File tree

1 file changed

+83
-8
lines changed

1 file changed

+83
-8
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertyName.java

+83-8
Original file line numberDiff line numberDiff line change
@@ -237,12 +237,7 @@ public boolean isAncestorOf(ConfigurationPropertyName name) {
237237
if (this.getNumberOfElements() >= name.getNumberOfElements()) {
238238
return false;
239239
}
240-
for (int i = this.elements.getSize() - 1; i >= 0; i--) {
241-
if (!elementEquals(this.elements, name.elements, i)) {
242-
return false;
243-
}
244-
}
245-
return true;
240+
return elementsEqual(name);
246241
}
247242

248243
@Override
@@ -309,15 +304,34 @@ public boolean equals(Object obj) {
309304
&& other.elements.canShortcutWithSource(ElementType.UNIFORM)) {
310305
return toString().equals(other.toString());
311306
}
307+
return elementsEqual(other);
308+
}
309+
310+
private boolean elementsEqual(ConfigurationPropertyName name) {
312311
for (int i = this.elements.getSize() - 1; i >= 0; i--) {
313-
if (!elementEquals(this.elements, other.elements, i)) {
312+
if (elementDiffers(this.elements, name.elements, i)) {
314313
return false;
315314
}
316315
}
317316
return true;
318317
}
319318

320-
private boolean elementEquals(Elements e1, Elements e2, int i) {
319+
private boolean elementDiffers(Elements e1, Elements e2, int i) {
320+
ElementType type1 = e1.getType(i);
321+
ElementType type2 = e2.getType(i);
322+
if (type1.allowsFastEqualityCheck() && type2.allowsFastEqualityCheck()) {
323+
return !fastElementEquals(e1, e2, i);
324+
}
325+
else if (type1.allowsDashIgnoringEqualityCheck()
326+
&& type2.allowsDashIgnoringEqualityCheck()) {
327+
return !dashIgnoringElementEquals(e1, e2, i);
328+
}
329+
else {
330+
return !defaultElementEquals(e1, e2, i);
331+
}
332+
}
333+
334+
private boolean defaultElementEquals(Elements e1, Elements e2, int i) {
321335
int l1 = e1.getLength(i);
322336
int l2 = e2.getLength(i);
323337
boolean indexed1 = e1.getType(i).isIndexed();
@@ -355,6 +369,59 @@ else if (ch1 != ch2) {
355369
return true;
356370
}
357371

372+
private boolean dashIgnoringElementEquals(Elements e1, Elements e2, int i) {
373+
int l1 = e1.getLength(i);
374+
int l2 = e2.getLength(i);
375+
int i1 = 0;
376+
int i2 = 0;
377+
while (i1 < l1) {
378+
if (i2 >= l2) {
379+
return false;
380+
}
381+
char ch1 = e1.charAt(i, i1);
382+
char ch2 = e2.charAt(i, i2);
383+
if (ch1 == '-') {
384+
i1++;
385+
}
386+
else if (ch2 == '-') {
387+
i2++;
388+
}
389+
else if (ch1 != ch2) {
390+
return false;
391+
}
392+
else {
393+
i1++;
394+
i2++;
395+
}
396+
}
397+
boolean indexed2 = e2.getType(i).isIndexed();
398+
while (i2 < l2) {
399+
char ch2 = e2.charAt(i, i2++);
400+
if (indexed2 || ch2 == '-') {
401+
return false;
402+
}
403+
}
404+
return true;
405+
}
406+
407+
private boolean fastElementEquals(Elements e1, Elements e2, int i) {
408+
int length1 = e1.getLength(i);
409+
int length2 = e2.getLength(i);
410+
if (length1 == length2) {
411+
int i1 = 0;
412+
while (length1-- != 0) {
413+
char ch1 = e1.charAt(i, i1);
414+
char ch2 = e2.charAt(i, i1);
415+
if (ch1 != ch2) {
416+
return false;
417+
}
418+
i1++;
419+
}
420+
return true;
421+
}
422+
return false;
423+
}
424+
358425
@Override
359426
public int hashCode() {
360427
return 0;
@@ -913,6 +980,14 @@ public boolean isIndexed() {
913980
return this.indexed;
914981
}
915982

983+
public boolean allowsFastEqualityCheck() {
984+
return this == UNIFORM || this == NUMERICALLY_INDEXED;
985+
}
986+
987+
public boolean allowsDashIgnoringEqualityCheck() {
988+
return allowsFastEqualityCheck() || this == DASHED;
989+
}
990+
916991
}
917992

918993
/**

0 commit comments

Comments
 (0)