8066291: Return unmodifiable set of zone IDs to optimize ZoneIdPrinterParser
Summary: Cache the available zones to speed up parsing
Reviewed-by: rriggs, scolebourne
--- a/jdk/src/java.base/share/classes/java/time/ZoneId.java Sun Nov 20 17:39:09 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/time/ZoneId.java Mon Nov 21 06:04:25 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -76,6 +76,7 @@
import java.time.zone.ZoneRules;
import java.time.zone.ZoneRulesException;
import java.time.zone.ZoneRulesProvider;
+import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
@@ -284,7 +285,7 @@
* @return a modifiable copy of the set of zone IDs, not null
*/
public static Set<String> getAvailableZoneIds() {
- return ZoneRulesProvider.getAvailableZoneIds();
+ return new HashSet<String>(ZoneRulesProvider.getAvailableZoneIds());
}
//-----------------------------------------------------------------------
--- a/jdk/src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java Sun Nov 20 17:39:09 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java Mon Nov 21 06:04:25 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,6 +77,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.Collections;
/**
* Provider of time-zone rules to the system.
@@ -137,6 +138,11 @@
*/
private static final ConcurrentMap<String, ZoneRulesProvider> ZONES = new ConcurrentHashMap<>(512, 0.75f, 2);
+ /**
+ * The zone ID data
+ */
+ private static volatile Set<String> ZONE_IDS;
+
static {
// if the property java.time.zone.DefaultZoneRulesProvider is
// set then its value is the class name of the default provider
@@ -194,10 +200,10 @@
* <p>
* These IDs are the string form of a {@link ZoneId}.
*
- * @return a modifiable copy of the set of zone IDs, not null
+ * @return the unmodifiable set of zone IDs, not null
*/
public static Set<String> getAvailableZoneIds() {
- return new HashSet<>(ZONES.keySet());
+ return ZONE_IDS;
}
/**
@@ -303,7 +309,7 @@
* @param provider the provider to register, not null
* @throws ZoneRulesException if unable to complete the registration
*/
- private static void registerProvider0(ZoneRulesProvider provider) {
+ private static synchronized void registerProvider0(ZoneRulesProvider provider) {
for (String zoneId : provider.provideZoneIds()) {
Objects.requireNonNull(zoneId, "zoneId");
ZoneRulesProvider old = ZONES.putIfAbsent(zoneId, provider);
@@ -313,6 +319,8 @@
", currently loading from provider: " + provider);
}
}
+ Set<String> combinedSet = new HashSet<String>(ZONES.keySet());
+ ZONE_IDS = Collections.unmodifiableSet(combinedSet);
}
/**
--- a/jdk/test/java/time/tck/java/time/zone/TCKZoneRulesProvider.java Sun Nov 20 17:39:09 2016 -0800
+++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneRulesProvider.java Mon Nov 21 06:04:25 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -91,10 +91,11 @@
public void test_getAvailableGroupIds() {
Set<String> zoneIds = ZoneRulesProvider.getAvailableZoneIds();
assertEquals(zoneIds.contains("Europe/London"), true);
- zoneIds.clear();
- assertEquals(zoneIds.size(), 0);
- Set<String> zoneIds2 = ZoneRulesProvider.getAvailableZoneIds();
- assertEquals(zoneIds2.contains("Europe/London"), true);
+ }
+
+ @Test(expectedExceptions=UnsupportedOperationException.class)
+ public void test_getAvailableGroupIds_modifyZoneId() {
+ ZoneRulesProvider.getAvailableZoneIds().clear();
}
//-----------------------------------------------------------------------