Commit 85e9a73e authored by Phillip Webb's avatar Phillip Webb

Add hashcode support to ConfigurationPropertyName

Provide a hashcode implementation for `ConfigurationPropertyName` so
that instances can be stored in Map without them all ending up in the
same bucket.

See gh-20625
parent 53099129
...@@ -64,6 +64,8 @@ public final class ConfigurationPropertyName implements Comparable<Configuration ...@@ -64,6 +64,8 @@ public final class ConfigurationPropertyName implements Comparable<Configuration
private String string; private String string;
private int hashCode;
private ConfigurationPropertyName(Elements elements) { private ConfigurationPropertyName(Elements elements) {
this.elements = elements; this.elements = elements;
this.uniformElements = new CharSequence[elements.getSize()]; this.uniformElements = new CharSequence[elements.getSize()];
...@@ -322,23 +324,39 @@ public final class ConfigurationPropertyName implements Comparable<Configuration ...@@ -322,23 +324,39 @@ public final class ConfigurationPropertyName implements Comparable<Configuration
} }
} }
private boolean defaultElementEquals(Elements e1, Elements e2, int i) { private boolean fastElementEquals(Elements e1, Elements e2, int i) {
int length1 = e1.getLength(i);
int length2 = e2.getLength(i);
if (length1 == length2) {
int i1 = 0;
while (length1-- != 0) {
char ch1 = e1.charAt(i, i1);
char ch2 = e2.charAt(i, i1);
if (ch1 != ch2) {
return false;
}
i1++;
}
return true;
}
return false;
}
private boolean dashIgnoringElementEquals(Elements e1, Elements e2, int i) {
int l1 = e1.getLength(i); int l1 = e1.getLength(i);
int l2 = e2.getLength(i); int l2 = e2.getLength(i);
boolean indexed1 = e1.getType(i).isIndexed();
boolean indexed2 = e2.getType(i).isIndexed();
int i1 = 0; int i1 = 0;
int i2 = 0; int i2 = 0;
while (i1 < l1) { while (i1 < l1) {
if (i2 >= l2) { if (i2 >= l2) {
return false; return false;
} }
char ch1 = indexed1 ? e1.charAt(i, i1) : Character.toLowerCase(e1.charAt(i, i1)); char ch1 = e1.charAt(i, i1);
char ch2 = indexed2 ? e2.charAt(i, i2) : Character.toLowerCase(e2.charAt(i, i2)); char ch2 = e2.charAt(i, i2);
if (!indexed1 && !ElementsParser.isAlphaNumeric(ch1)) { if (ch1 == '-') {
i1++; i1++;
} }
else if (!indexed2 && !ElementsParser.isAlphaNumeric(ch2)) { else if (ch2 == '-') {
i2++; i2++;
} }
else if (ch1 != ch2) { else if (ch1 != ch2) {
...@@ -350,12 +368,12 @@ public final class ConfigurationPropertyName implements Comparable<Configuration ...@@ -350,12 +368,12 @@ public final class ConfigurationPropertyName implements Comparable<Configuration
} }
} }
if (i2 < l2) { if (i2 < l2) {
if (indexed2) { if (e2.getType(i).isIndexed()) {
return false; return false;
} }
do { do {
char ch2 = Character.toLowerCase(e2.charAt(i, i2++)); char ch2 = e2.charAt(i, i2++);
if (ElementsParser.isAlphaNumeric(ch2)) { if (ch2 != '-') {
return false; return false;
} }
} }
...@@ -364,21 +382,23 @@ public final class ConfigurationPropertyName implements Comparable<Configuration ...@@ -364,21 +382,23 @@ public final class ConfigurationPropertyName implements Comparable<Configuration
return true; return true;
} }
private boolean dashIgnoringElementEquals(Elements e1, Elements e2, int i) { private boolean defaultElementEquals(Elements e1, Elements e2, int i) {
int l1 = e1.getLength(i); int l1 = e1.getLength(i);
int l2 = e2.getLength(i); int l2 = e2.getLength(i);
boolean indexed1 = e1.getType(i).isIndexed();
boolean indexed2 = e2.getType(i).isIndexed();
int i1 = 0; int i1 = 0;
int i2 = 0; int i2 = 0;
while (i1 < l1) { while (i1 < l1) {
if (i2 >= l2) { if (i2 >= l2) {
return false; return false;
} }
char ch1 = e1.charAt(i, i1); char ch1 = indexed1 ? e1.charAt(i, i1) : Character.toLowerCase(e1.charAt(i, i1));
char ch2 = e2.charAt(i, i2); char ch2 = indexed2 ? e2.charAt(i, i2) : Character.toLowerCase(e2.charAt(i, i2));
if (ch1 == '-') { if (!indexed1 && !ElementsParser.isAlphaNumeric(ch1)) {
i1++; i1++;
} }
else if (ch2 == '-') { else if (!indexed2 && !ElementsParser.isAlphaNumeric(ch2)) {
i2++; i2++;
} }
else if (ch1 != ch2) { else if (ch1 != ch2) {
...@@ -390,12 +410,12 @@ public final class ConfigurationPropertyName implements Comparable<Configuration ...@@ -390,12 +410,12 @@ public final class ConfigurationPropertyName implements Comparable<Configuration
} }
} }
if (i2 < l2) { if (i2 < l2) {
if (e2.getType(i).isIndexed()) { if (indexed2) {
return false; return false;
} }
do { do {
char ch2 = e2.charAt(i, i2++); char ch2 = Character.toLowerCase(e2.charAt(i, i2++));
if (ch2 != '-') { if (ElementsParser.isAlphaNumeric(ch2)) {
return false; return false;
} }
} }
...@@ -404,27 +424,28 @@ public final class ConfigurationPropertyName implements Comparable<Configuration ...@@ -404,27 +424,28 @@ public final class ConfigurationPropertyName implements Comparable<Configuration
return true; return true;
} }
private boolean fastElementEquals(Elements e1, Elements e2, int i) { @Override
int length1 = e1.getLength(i); public int hashCode() {
int length2 = e2.getLength(i); int hashCode = this.hashCode;
if (length1 == length2) { Elements elements = this.elements;
int i1 = 0; if (hashCode == 0 && elements.getSize() != 0) {
while (length1-- != 0) { for (int elementIndex = 0; elementIndex < elements.getSize(); elementIndex++) {
char ch1 = e1.charAt(i, i1); int elementHashCode = 0;
char ch2 = e2.charAt(i, i1); boolean indexed = elements.getType(elementIndex).isIndexed();
if (ch1 != ch2) { int length = elements.getLength(elementIndex);
return false; for (int i = 0; i < length; i++) {
char ch = elements.charAt(elementIndex, i);
if (!indexed) {
ch = Character.toLowerCase(ch);
}
if (ElementsParser.isAlphaNumeric(ch)) {
elementHashCode = 31 * elementHashCode + ch;
}
} }
i1++; hashCode = 31 * hashCode + elementHashCode;
} }
return true;
} }
return false; return hashCode;
}
@Override
public int hashCode() {
return 0;
} }
@Override @Override
......
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -545,17 +545,18 @@ class ConfigurationPropertyNameTests { ...@@ -545,17 +545,18 @@ class ConfigurationPropertyNameTests {
ConfigurationPropertyName n13 = ConfigurationPropertyName.of("f-o-o[b-a-r--]"); ConfigurationPropertyName n13 = ConfigurationPropertyName.of("f-o-o[b-a-r--]");
ConfigurationPropertyName n14 = ConfigurationPropertyName.of("[1]"); ConfigurationPropertyName n14 = ConfigurationPropertyName.of("[1]");
ConfigurationPropertyName n15 = ConfigurationPropertyName.of("[-1]"); ConfigurationPropertyName n15 = ConfigurationPropertyName.of("[-1]");
assertThat(n01.hashCode()).isEqualTo(n02.hashCode());
assertThat(n01.hashCode()).isEqualTo(n02.hashCode());
assertThat(n01.hashCode()).isEqualTo(n03.hashCode());
assertThat(n01.hashCode()).isEqualTo(n04.hashCode());
assertThat(n01.hashCode()).isEqualTo(n11.hashCode());
assertThat((Object) n01).isEqualTo(n01); assertThat((Object) n01).isEqualTo(n01);
assertThat(n01.hashCode()).isEqualTo(n01.hashCode());
assertThat((Object) n01).isEqualTo(n02); assertThat((Object) n01).isEqualTo(n02);
assertThat(n01.hashCode()).isEqualTo(n02.hashCode());
assertThat((Object) n01).isEqualTo(n03); assertThat((Object) n01).isEqualTo(n03);
assertThat(n01.hashCode()).isEqualTo(n03.hashCode());
assertThat((Object) n01).isEqualTo(n04); assertThat((Object) n01).isEqualTo(n04);
assertThat(n01.hashCode()).isEqualTo(n04.hashCode());
assertThat((Object) n11).isEqualTo(n03); assertThat((Object) n11).isEqualTo(n03);
assertThat(n11.hashCode()).isEqualTo(n03.hashCode());
assertThat((Object) n03).isEqualTo(n11); assertThat((Object) n03).isEqualTo(n11);
assertThat(n03.hashCode()).isEqualTo(n11.hashCode());
assertThat((Object) n01).isNotEqualTo(n05); assertThat((Object) n01).isNotEqualTo(n05);
assertThat((Object) n01).isNotEqualTo(n06); assertThat((Object) n01).isNotEqualTo(n06);
assertThat((Object) n07).isNotEqualTo(n08); assertThat((Object) n07).isNotEqualTo(n08);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment