|
16 | 16 | import java.util.Objects; |
17 | 17 | import java.util.RandomAccess; |
18 | 18 | import java.util.Set; |
| 19 | +import java.util.concurrent.ConcurrentHashMap; |
19 | 20 | import java.util.concurrent.ConcurrentMap; |
20 | 21 | import java.util.concurrent.atomic.AtomicBoolean; |
21 | 22 | import java.util.concurrent.atomic.AtomicInteger; |
@@ -144,6 +145,78 @@ public final class MultiKeyMap<V> implements ConcurrentMap<Object, V> { |
144 | 145 | private static final String EMOJI_KEY = "🆔 "; // ID for keys (with space) |
145 | 146 | private static final String EMOJI_VALUE = "🟣 "; // Purple circle for values (with space) |
146 | 147 |
|
| 148 | + // JDK DTO array types that are guaranteed to be 1D (elements can't be arrays/collections) |
| 149 | + // Using ConcurrentHashMap-backed Set for thread-safe, high-performance lookups |
| 150 | + private static final Set<Class<?>> SIMPLE_ARRAY_TYPES = Collections.newSetFromMap(new ConcurrentHashMap<>()); |
| 151 | + static { |
| 152 | + // Wrapper types |
| 153 | + SIMPLE_ARRAY_TYPES.add(String[].class); |
| 154 | + SIMPLE_ARRAY_TYPES.add(Integer[].class); |
| 155 | + SIMPLE_ARRAY_TYPES.add(Long[].class); |
| 156 | + SIMPLE_ARRAY_TYPES.add(Double[].class); |
| 157 | + SIMPLE_ARRAY_TYPES.add(Float[].class); |
| 158 | + SIMPLE_ARRAY_TYPES.add(Boolean[].class); |
| 159 | + SIMPLE_ARRAY_TYPES.add(Character[].class); |
| 160 | + SIMPLE_ARRAY_TYPES.add(Byte[].class); |
| 161 | + SIMPLE_ARRAY_TYPES.add(Short[].class); |
| 162 | + |
| 163 | + // Date/Time types |
| 164 | + SIMPLE_ARRAY_TYPES.add(Date[].class); |
| 165 | + SIMPLE_ARRAY_TYPES.add(java.sql.Date[].class); |
| 166 | + SIMPLE_ARRAY_TYPES.add(java.sql.Time[].class); |
| 167 | + SIMPLE_ARRAY_TYPES.add(java.sql.Timestamp[].class); |
| 168 | + |
| 169 | + // java.time types (Java 8+) |
| 170 | + SIMPLE_ARRAY_TYPES.add(java.time.LocalDate[].class); |
| 171 | + SIMPLE_ARRAY_TYPES.add(java.time.LocalTime[].class); |
| 172 | + SIMPLE_ARRAY_TYPES.add(java.time.LocalDateTime[].class); |
| 173 | + SIMPLE_ARRAY_TYPES.add(java.time.ZonedDateTime[].class); |
| 174 | + SIMPLE_ARRAY_TYPES.add(java.time.OffsetDateTime[].class); |
| 175 | + SIMPLE_ARRAY_TYPES.add(java.time.OffsetTime[].class); |
| 176 | + SIMPLE_ARRAY_TYPES.add(java.time.Instant[].class); |
| 177 | + SIMPLE_ARRAY_TYPES.add(java.time.Duration[].class); |
| 178 | + SIMPLE_ARRAY_TYPES.add(java.time.Period[].class); |
| 179 | + SIMPLE_ARRAY_TYPES.add(java.time.Year[].class); |
| 180 | + SIMPLE_ARRAY_TYPES.add(java.time.YearMonth[].class); |
| 181 | + SIMPLE_ARRAY_TYPES.add(java.time.MonthDay[].class); |
| 182 | + SIMPLE_ARRAY_TYPES.add(java.time.ZoneId[].class); |
| 183 | + SIMPLE_ARRAY_TYPES.add(java.time.ZoneOffset[].class); |
| 184 | + |
| 185 | + // Math/Precision types |
| 186 | + SIMPLE_ARRAY_TYPES.add(java.math.BigInteger[].class); |
| 187 | + SIMPLE_ARRAY_TYPES.add(java.math.BigDecimal[].class); |
| 188 | + |
| 189 | + // Network/IO types |
| 190 | + SIMPLE_ARRAY_TYPES.add(java.net.URL[].class); |
| 191 | + SIMPLE_ARRAY_TYPES.add(java.net.URI[].class); |
| 192 | + SIMPLE_ARRAY_TYPES.add(java.net.InetAddress[].class); |
| 193 | + SIMPLE_ARRAY_TYPES.add(java.net.Inet4Address[].class); |
| 194 | + SIMPLE_ARRAY_TYPES.add(java.net.Inet6Address[].class); |
| 195 | + SIMPLE_ARRAY_TYPES.add(java.io.File[].class); |
| 196 | + SIMPLE_ARRAY_TYPES.add(java.nio.file.Path[].class); |
| 197 | + |
| 198 | + // Utility types |
| 199 | + SIMPLE_ARRAY_TYPES.add(java.util.UUID[].class); |
| 200 | + SIMPLE_ARRAY_TYPES.add(java.util.Locale[].class); |
| 201 | + SIMPLE_ARRAY_TYPES.add(java.util.Currency[].class); |
| 202 | + SIMPLE_ARRAY_TYPES.add(java.util.TimeZone[].class); |
| 203 | + SIMPLE_ARRAY_TYPES.add(java.util.regex.Pattern[].class); |
| 204 | + |
| 205 | + // AWT/Swing basic types (immutable DTOs) |
| 206 | + SIMPLE_ARRAY_TYPES.add(java.awt.Color[].class); |
| 207 | + SIMPLE_ARRAY_TYPES.add(java.awt.Font[].class); |
| 208 | + SIMPLE_ARRAY_TYPES.add(java.awt.Dimension[].class); |
| 209 | + SIMPLE_ARRAY_TYPES.add(java.awt.Point[].class); |
| 210 | + SIMPLE_ARRAY_TYPES.add(java.awt.Rectangle[].class); |
| 211 | + SIMPLE_ARRAY_TYPES.add(java.awt.Insets[].class); |
| 212 | + |
| 213 | + // Enum arrays are also simple (enums can't contain collections/arrays) |
| 214 | + SIMPLE_ARRAY_TYPES.add(java.time.DayOfWeek[].class); |
| 215 | + SIMPLE_ARRAY_TYPES.add(java.time.Month[].class); |
| 216 | + SIMPLE_ARRAY_TYPES.add(java.nio.file.StandardOpenOption[].class); |
| 217 | + SIMPLE_ARRAY_TYPES.add(java.nio.file.LinkOption[].class); |
| 218 | + } |
| 219 | + |
147 | 220 | // Static flag to log stripe configuration only once per JVM |
148 | 221 | private static final AtomicBoolean STRIPE_CONFIG_LOGGED = new AtomicBoolean(false); |
149 | 222 |
|
@@ -1184,22 +1257,19 @@ private NormalizedKey process1DTypedArray(Object arr) { |
1184 | 1257 | Class<?> clazz = arr.getClass(); |
1185 | 1258 |
|
1186 | 1259 | // Primitive arrays are already handled in flattenKey() and never reach here |
1187 | | - // Only handle common non-primitive array types for optimization |
| 1260 | + // Handle JDK DTO array types for optimization (elements guaranteed to be simple) |
1188 | 1261 |
|
1189 | | - // Handle common Object[] subtypes efficiently (these can't contain nested arrays/collections) |
1190 | | - if (clazz == String[].class || clazz == Integer[].class || clazz == Long[].class || |
1191 | | - clazz == Double[].class || clazz == Date[].class || clazz == Boolean[].class || |
1192 | | - clazz == Float[].class || clazz == Short[].class || clazz == Byte[].class || |
1193 | | - clazz == Character[].class) { |
| 1262 | + // Handle simple array types efficiently (these can't contain nested arrays/collections) |
| 1263 | + if (SIMPLE_ARRAY_TYPES.contains(clazz)) { |
1194 | 1264 |
|
1195 | 1265 | Object[] objArray = (Object[]) arr; |
1196 | 1266 | final int len = objArray.length; |
1197 | 1267 | if (len == 0) { |
1198 | 1268 | return new NormalizedKey(objArray, 0); |
1199 | 1269 | } |
1200 | 1270 |
|
1201 | | - // These array types are always 1D (their elements can't be arrays or collections) |
1202 | | - // Optimized: Direct array access without checks |
| 1271 | + // JDK DTO array types are always 1D (their elements can't be arrays or collections) |
| 1272 | + // Optimized: Direct array access without nested structure checks |
1203 | 1273 | int h = 1; |
1204 | 1274 | for (int i = 0; i < len; i++) { |
1205 | 1275 | final Object o = objArray[i]; |
|
0 commit comments