Skip to content

Commit fcbe7db

Browse files
author
Claude4.0s
committed
support well-known JDK types in array form
1 parent 1ebe448 commit fcbe7db

File tree

2 files changed

+79
-9
lines changed

2 files changed

+79
-9
lines changed

src/main/java/com/cedarsoftware/util/MultiKeyMap.java

Lines changed: 78 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.Objects;
1717
import java.util.RandomAccess;
1818
import java.util.Set;
19+
import java.util.concurrent.ConcurrentHashMap;
1920
import java.util.concurrent.ConcurrentMap;
2021
import java.util.concurrent.atomic.AtomicBoolean;
2122
import java.util.concurrent.atomic.AtomicInteger;
@@ -144,6 +145,78 @@ public final class MultiKeyMap<V> implements ConcurrentMap<Object, V> {
144145
private static final String EMOJI_KEY = "🆔 "; // ID for keys (with space)
145146
private static final String EMOJI_VALUE = "🟣 "; // Purple circle for values (with space)
146147

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+
147220
// Static flag to log stripe configuration only once per JVM
148221
private static final AtomicBoolean STRIPE_CONFIG_LOGGED = new AtomicBoolean(false);
149222

@@ -1184,22 +1257,19 @@ private NormalizedKey process1DTypedArray(Object arr) {
11841257
Class<?> clazz = arr.getClass();
11851258

11861259
// 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)
11881261

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)) {
11941264

11951265
Object[] objArray = (Object[]) arr;
11961266
final int len = objArray.length;
11971267
if (len == 0) {
11981268
return new NormalizedKey(objArray, 0);
11991269
}
12001270

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
12031273
int h = 1;
12041274
for (int i = 0; i < len; i++) {
12051275
final Object o = objArray[i];

src/test/java/com/cedarsoftware/util/MultiKeyMapPerformanceComparisonTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ private static class TestResult {
7777
}
7878
}
7979

80-
// @Disabled
80+
@Disabled
8181
@Test
8282
void comparePerformance() {
8383
LOG.info("=== Cedar vs Apache MultiKeyMap Performance Comparison ===");

0 commit comments

Comments
 (0)