@@ -291,7 +291,7 @@ public boolean isAncestorOf(ConfigurationPropertyName name) {
291
291
if (getNumberOfElements () >= name .getNumberOfElements ()) {
292
292
return false ;
293
293
}
294
- return elementsEqual (name );
294
+ return endsWithElementsEqualTo (name );
295
295
}
296
296
297
297
@ Override
@@ -357,10 +357,20 @@ public boolean equals(Object obj) {
357
357
&& other .elements .canShortcutWithSource (ElementType .UNIFORM )) {
358
358
return toString ().equals (other .toString ());
359
359
}
360
- return elementsEqual (other );
360
+ if (hashCode () != other .hashCode ()) {
361
+ return false ;
362
+ }
363
+ if (toStringMatches (toString (), other .toString ())) {
364
+ return true ;
365
+ }
366
+ return endsWithElementsEqualTo (other );
367
+ }
368
+
369
+ private boolean toStringMatches (String s1 , String s2 ) {
370
+ return s1 .hashCode () == s2 .hashCode () && s1 .equals (s2 );
361
371
}
362
372
363
- private boolean elementsEqual (ConfigurationPropertyName name ) {
373
+ private boolean endsWithElementsEqualTo (ConfigurationPropertyName name ) {
364
374
for (int i = this .elements .getSize () - 1 ; i >= 0 ; i --) {
365
375
if (elementDiffers (this .elements , name .elements , i )) {
366
376
return false ;
@@ -508,19 +518,7 @@ public int hashCode() {
508
518
Elements elements = this .elements ;
509
519
if (hashCode == 0 && elements .getSize () != 0 ) {
510
520
for (int elementIndex = 0 ; elementIndex < elements .getSize (); elementIndex ++) {
511
- int elementHashCode = 0 ;
512
- boolean indexed = elements .getType (elementIndex ).isIndexed ();
513
- int length = elements .getLength (elementIndex );
514
- for (int i = 0 ; i < length ; i ++) {
515
- char ch = elements .charAt (elementIndex , i );
516
- if (!indexed ) {
517
- ch = Character .toLowerCase (ch );
518
- }
519
- if (ElementsParser .isAlphaNumeric (ch )) {
520
- elementHashCode = 31 * elementHashCode + ch ;
521
- }
522
- }
523
- hashCode = 31 * hashCode + elementHashCode ;
521
+ hashCode = 31 * hashCode + elements .hashCode (elementIndex );
524
522
}
525
523
this .hashCode = hashCode ;
526
524
}
@@ -737,7 +735,7 @@ private static class Elements {
737
735
738
736
private static final ElementType [] NO_TYPE = {};
739
737
740
- public static final Elements EMPTY = new Elements ("" , 0 , NO_POSITION , NO_POSITION , NO_TYPE , null );
738
+ public static final Elements EMPTY = new Elements ("" , 0 , NO_POSITION , NO_POSITION , NO_TYPE , null , null );
741
739
742
740
private final CharSequence source ;
743
741
@@ -749,6 +747,8 @@ private static class Elements {
749
747
750
748
private final ElementType [] type ;
751
749
750
+ private final int [] hashCode ;
751
+
752
752
/**
753
753
* Contains any resolved elements or can be {@code null} if there aren't any.
754
754
* Resolved elements allow us to modify the element values in some way (or example
@@ -759,30 +759,35 @@ private static class Elements {
759
759
*/
760
760
private final CharSequence [] resolved ;
761
761
762
- Elements (CharSequence source , int size , int [] start , int [] end , ElementType [] type , CharSequence [] resolved ) {
762
+ Elements (CharSequence source , int size , int [] start , int [] end , ElementType [] type , int [] hashCode ,
763
+ CharSequence [] resolved ) {
763
764
this .source = source ;
764
765
this .size = size ;
765
766
this .start = start ;
766
767
this .end = end ;
767
768
this .type = type ;
769
+ this .hashCode = (hashCode != null ) ? hashCode : new int [size ];
768
770
this .resolved = resolved ;
769
771
}
770
772
771
773
Elements append (Elements additional ) {
772
774
int size = this .size + additional .size ;
773
775
ElementType [] type = new ElementType [size ];
776
+ int [] hashCode = new int [size ];
774
777
System .arraycopy (this .type , 0 , type , 0 , this .size );
775
778
System .arraycopy (additional .type , 0 , type , this .size , additional .size );
779
+ System .arraycopy (this .hashCode , 0 , hashCode , 0 , this .size );
780
+ System .arraycopy (additional .hashCode , 0 , hashCode , this .size , additional .size );
776
781
CharSequence [] resolved = newResolved (0 , size );
777
782
for (int i = 0 ; i < additional .size ; i ++) {
778
783
resolved [this .size + i ] = additional .get (i );
779
784
}
780
- return new Elements (this .source , size , this .start , this .end , type , resolved );
785
+ return new Elements (this .source , size , this .start , this .end , type , hashCode , resolved );
781
786
}
782
787
783
788
Elements chop (int size ) {
784
789
CharSequence [] resolved = newResolved (0 , size );
785
- return new Elements (this .source , size , this .start , this .end , this .type , resolved );
790
+ return new Elements (this .source , size , this .start , this .end , this .type , this . hashCode , resolved );
786
791
}
787
792
788
793
Elements subElements (int offset ) {
@@ -794,7 +799,9 @@ Elements subElements(int offset) {
794
799
System .arraycopy (this .end , offset , end , 0 , size );
795
800
ElementType [] type = new ElementType [size ];
796
801
System .arraycopy (this .type , offset , type , 0 , size );
797
- return new Elements (this .source , size , start , end , type , resolved );
802
+ int [] hashCode = new int [size ];
803
+ System .arraycopy (this .hashCode , offset , hashCode , 0 , size );
804
+ return new Elements (this .source , size , start , end , type , hashCode , resolved );
798
805
}
799
806
800
807
private CharSequence [] newResolved (int offset , int size ) {
@@ -839,6 +846,25 @@ ElementType getType(int index) {
839
846
return this .type [index ];
840
847
}
841
848
849
+ int hashCode (int index ) {
850
+ int hashCode = this .hashCode [index ];
851
+ if (hashCode == 0 ) {
852
+ boolean indexed = getType (index ).isIndexed ();
853
+ int length = getLength (index );
854
+ for (int i = 0 ; i < length ; i ++) {
855
+ char ch = charAt (index , i );
856
+ if (!indexed ) {
857
+ ch = Character .toLowerCase (ch );
858
+ }
859
+ if (ElementsParser .isAlphaNumeric (ch )) {
860
+ hashCode = 31 * hashCode + ch ;
861
+ }
862
+ }
863
+ this .hashCode [index ] = hashCode ;
864
+ }
865
+ return hashCode ;
866
+ }
867
+
842
868
CharSequence getSource () {
843
869
return this .source ;
844
870
}
@@ -951,7 +977,7 @@ else if (!type.isIndexed() && ch == this.separator) {
951
977
type = ElementType .NON_UNIFORM ;
952
978
}
953
979
add (start , length , type , valueProcessor );
954
- return new Elements (this .source , this .size , this .start , this .end , this .type , this .resolved );
980
+ return new Elements (this .source , this .size , this .start , this .end , this .type , null , this .resolved );
955
981
}
956
982
957
983
private ElementType updateType (ElementType existingType , char ch , int index ) {
0 commit comments