src/java.base/share/classes/java/lang/String.java
Print this page
rev 13827 : 8151384: Examine sun.misc.ASCIICaseInsensitiveComparator
Reviewed-by:
@@ -1220,20 +1220,49 @@
private static final long serialVersionUID = 8575799808933029326L;
public int compare(String s1, String s2) {
byte v1[] = s1.value;
byte v2[] = s2.value;
- int n1 = s1.length();
- int n2 = s2.length();
boolean s1IsLatin1 = s1.isLatin1();
- boolean s2IsLatin1 = s2.isLatin1();
- int min = Math.min(n1, n2);
- for (int i = 0; i < min; i++) {
- char c1 = s1IsLatin1 ? StringLatin1.getChar(v1, i)
- : StringUTF16.getChar(v1, i);
- char c2 = s2IsLatin1 ? StringLatin1.getChar(v2, i)
- : StringUTF16.getChar(v2, i);
+ if (s1.coder() == s2.coder()) {
+ return s1IsLatin1 ? compareLatin1(v1, v2)
+ : compareUTF16(v1, v2);
+ }
+ return s1IsLatin1 ? compareLatin1ToUTF16(v1, v2)
+ : compareLatin1ToUTF16(v2, v1) * -1;
+ }
+
+ private static final int compareLatin1(byte[] v1, byte[] v2) {
+ int len1 = v1.length;
+ int len2 = v2.length;
+ int lim = Math.min(len1, len2);
+ for (int i = 0; i < lim; i++) {
+ char c1 = StringLatin1.getChar(v1, i);
+ char c2 = StringLatin1.getChar(v2, i);
+ if (c1 != c2) {
+ c1 = (char) CharacterDataLatin1.instance.toUpperCase(c1);
+ c2 = (char) CharacterDataLatin1.instance.toUpperCase(c2);
+ if (c1 != c2) {
+ c1 = (char) CharacterDataLatin1.instance.toLowerCase(c1);
+ c2 = (char) CharacterDataLatin1.instance.toLowerCase(c2);
+ if (c1 != c2) {
+ // No overflow because of numeric promotion
+ return c1 - c2;
+ }
+ }
+ }
+ }
+ return len1 - len2;
+ }
+
+ private static final int compareUTF16(byte[] v1, byte[] v2) {
+ int len1 = StringUTF16.length(v1);
+ int len2 = StringUTF16.length(v2);
+ int lim = Math.min(len1, len2);
+ for (int i = 0; i < lim; i++) {
+ char c1 = StringUTF16.getChar(v1, i);
+ char c2 = StringUTF16.getChar(v2, i);
if (c1 != c2) {
c1 = Character.toUpperCase(c1);
c2 = Character.toUpperCase(c2);
if (c1 != c2) {
c1 = Character.toLowerCase(c1);
@@ -1243,11 +1272,34 @@
return c1 - c2;
}
}
}
}
- return n1 - n2;
+ return len1 - len2;
+ }
+
+ private static final int compareLatin1ToUTF16(byte[] v1, byte[] v2) {
+ int len1 = v1.length;
+ int len2 = StringUTF16.length(v2);
+ int lim = Math.min(len1, len2);
+ for (int i = 0; i < lim; i++) {
+ char c1 = StringLatin1.getChar(v1, i);
+ char c2 = StringUTF16.getChar(v2, i);
+ if (c1 != c2) {
+ c1 = (char) CharacterDataLatin1.instance.toUpperCase(c1);
+ c2 = Character.toUpperCase(c2);
+ if (c1 != c2) {
+ c1 = (char) CharacterDataLatin1.instance.toLowerCase(c1);
+ c2 = Character.toLowerCase(c2);
+ if (c1 != c2) {
+ // No overflow because of numeric promotion
+ return c1 - c2;
+ }
+ }
+ }
+ }
+ return len1 - len2;
}
/** Replaces the de-serialized object. */
private Object readResolve() { return CASE_INSENSITIVE_ORDER; }
}