File tree 2 files changed +34
-3
lines changed
main/java/org/apache/avro/util
test/java/org/apache/avro/util
2 files changed +34
-3
lines changed Original file line number Diff line number Diff line change @@ -68,6 +68,11 @@ public Utf8(byte[] bytes) {
68
68
this .length = length ;
69
69
}
70
70
71
+ Utf8 (String string , int length ) {
72
+ this (string );
73
+ this .length = length ;
74
+ }
75
+
71
76
/**
72
77
* Return UTF-8 encoded bytes. Only valid through {@link #getByteLength()}
73
78
* assuming the bytes have been fully copied into the underlying buffer from the
@@ -173,9 +178,15 @@ public int hashCode() {
173
178
if (h == 0 ) {
174
179
byte [] bytes = this .bytes ;
175
180
int length = this .length ;
176
- h = 1 ;
177
- for (int i = 0 ; i < length ; i ++) {
178
- h = h * 31 + bytes [i ];
181
+ // If the array is filled, use the underlying JDK hash functionality.
182
+ // Starting with JDK 21, the underlying implementation is vectorized.
183
+ if (length > 7 && bytes .length == length ) {
184
+ h = Arrays .hashCode (bytes );
185
+ } else {
186
+ h = 1 ;
187
+ for (int i = 0 ; i < length ; i ++) {
188
+ h = h * 31 + bytes [i ];
189
+ }
179
190
}
180
191
this .hash = h ;
181
192
}
Original file line number Diff line number Diff line change @@ -99,6 +99,26 @@ void hashCodeReused() {
99
99
assertEquals (4122302 , u .hashCode ());
100
100
}
101
101
102
+ /**
103
+ * There are two different code paths that hashcode() can call depending on the
104
+ * state of the internal buffer. If the buffer is full (string length is equal
105
+ * to buffer length) then the JDK hashcode function can be used. However, if the
106
+ * buffer is not full (string length is less than the internal buffer length),
107
+ * then the JDK does not support this prior to JDK 23 and a scalar
108
+ * implementation is the only option today. This difference can be resolved with
109
+ * JDK 23 as it supports both cases.
110
+ */
111
+ @ Test
112
+ void hashCodeBasedOnCapacity () {
113
+ // string = 8; buffer = 8
114
+ Utf8 fullCapacity = new Utf8 ("abcdefgh" , 8 );
115
+
116
+ // string = 8; buffer = 9
117
+ Utf8 partialCapacity = new Utf8 ("abcdefghX" , 8 );
118
+
119
+ assertEquals (fullCapacity .hashCode (), partialCapacity .hashCode ());
120
+ }
121
+
102
122
@ Test
103
123
void oversizeUtf8 () {
104
124
Utf8 u = new Utf8 ();
You can’t perform that action at this time.
0 commit comments