From 3d7536e60b51bad4f5eb6faa8efd8e18f13c28e2 Mon Sep 17 00:00:00 2001 From: Markus Scherer Date: Mon, 16 May 2016 16:36:31 +0000 Subject: [PATCH] ICU-7434 switch NumberingSystem from SimpleCache to SoftCache X-SVN-Rev: 38743 --- .../src/com/ibm/icu/text/NumberingSystem.java | 123 ++++++++++-------- 1 file changed, 72 insertions(+), 51 deletions(-) diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/NumberingSystem.java b/icu4j/main/classes/core/src/com/ibm/icu/text/NumberingSystem.java index 131e188c88e..5aa33d78f7b 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/NumberingSystem.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/NumberingSystem.java @@ -11,10 +11,10 @@ import java.util.ArrayList; import java.util.Locale; import java.util.MissingResourceException; -import com.ibm.icu.impl.ICUCache; +import com.ibm.icu.impl.CacheBase; import com.ibm.icu.impl.ICUData; import com.ibm.icu.impl.ICUResourceBundle; -import com.ibm.icu.impl.SimpleCache; +import com.ibm.icu.impl.SoftCache; import com.ibm.icu.lang.UCharacter; import com.ibm.icu.util.ULocale; import com.ibm.icu.util.ULocale.Category; @@ -33,6 +33,7 @@ import com.ibm.icu.util.UResourceBundleIterator; * @stable ICU 4.2 */ public class NumberingSystem { + private static final String[] OTHER_NS_KEYWORDS = { "native", "traditional", "finance" }; /** * Default constructor. Returns a numbering system that uses the Western decimal @@ -111,13 +112,8 @@ public class NumberingSystem { * @stable ICU 4.2 */ public static NumberingSystem getInstance(ULocale locale) { - - final String[] OTHER_NS_KEYWORDS = { "native", "traditional", "finance" }; - - NumberingSystem ns; - Boolean nsResolved = true; - // Check for @numbers + boolean nsResolved = true; String numbersKeyword = locale.getKeywordValue("numbers"); if (numbersKeyword != null ) { for ( String keyword : OTHER_NS_KEYWORDS ) { @@ -132,54 +128,72 @@ public class NumberingSystem { } if (nsResolved) { - ns = getInstanceByName(numbersKeyword); - if ( ns != null ) { + NumberingSystem ns = getInstanceByName(numbersKeyword); + if (ns != null) { return ns; - } else { // if @numbers keyword points to a bogus numbering system name, we return the default for the locale - numbersKeyword = "default"; - nsResolved = false; } + // If the @numbers keyword points to a bogus numbering system name, + // we return the default for the locale. + numbersKeyword = "default"; } - + // Attempt to get the numbering system from the cache String baseName = locale.getBaseName(); - ns = cachedLocaleData.get(baseName+"@numbers="+numbersKeyword); - if (ns != null ) { - return ns; + // TODO: Caching by locale+numbersKeyword could yield a large cache. + // Try to load for each locale the mappings from OTHER_NS_KEYWORDS and default + // to real numbering system names; can we get those from supplemental data? + // Then look up those mappings for the locale and resolve the keyword. + String key = baseName+"@numbers="+numbersKeyword; + LocaleLookupData localeLookupData = new LocaleLookupData(locale, numbersKeyword); + return cachedLocaleData.getInstance(key, localeLookupData); + } + + private static class LocaleLookupData { + public final ULocale locale; + public final String numbersKeyword; + + LocaleLookupData(ULocale locale, String numbersKeyword) { + this.locale = locale; + this.numbersKeyword = numbersKeyword; + } + } + + static NumberingSystem lookupInstanceByLocale(LocaleLookupData localeLookupData) { + ULocale locale = localeLookupData.locale; + ICUResourceBundle rb; + try { + rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, locale); + rb = rb.getWithFallback("NumberElements"); + } catch (MissingResourceException ex) { + return new NumberingSystem(); } - - // Cache miss, create new instance - String originalNumbersKeyword = numbersKeyword; + String numbersKeyword = localeLookupData.numbersKeyword; String resolvedNumberingSystem = null; - while (!nsResolved) { + for (;;) { try { - ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME,locale); - rb = rb.getWithFallback("NumberElements"); resolvedNumberingSystem = rb.getStringWithFallback(numbersKeyword); - nsResolved = true; + break; } catch (MissingResourceException ex) { // Fall back behavior as defined in TR35 - if (numbersKeyword.equals("native") || numbersKeyword.equals("finance")) { - numbersKeyword = "default"; - } else if (numbersKeyword.equals("traditional")) { - numbersKeyword = "native"; - } else { - nsResolved = true; - } - } + if (numbersKeyword.equals("native") || numbersKeyword.equals("finance")) { + numbersKeyword = "default"; + } else if (numbersKeyword.equals("traditional")) { + numbersKeyword = "native"; + } else { + break; + } + } } + NumberingSystem ns = null; if (resolvedNumberingSystem != null) { ns = getInstanceByName(resolvedNumberingSystem); } - - if ( ns == null ) { + + if (ns == null) { ns = new NumberingSystem(); } - - cachedLocaleData.put(baseName+"@numbers="+originalNumbersKeyword, ns); return ns; - } /** @@ -202,16 +216,14 @@ public class NumberingSystem { * @stable ICU 4.2 */ public static NumberingSystem getInstanceByName(String name) { + // Get the numbering system from the cache. + return cachedStringData.getInstance(name, null /* unused */); + } + + private static NumberingSystem lookupInstanceByName(String name) { int radix; boolean isAlgorithmic; String description; - - // Get the numbering system from the cache - NumberingSystem ns = cachedStringData.get(name); - if (ns != null ) { - return ns; - } - try { UResourceBundle numberingSystemsInfo = UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, "numberingSystems"); UResourceBundle nsCurrent = numberingSystemsInfo.get("numberingSystems"); @@ -229,9 +241,7 @@ public class NumberingSystem { return null; } - ns = getInstance(name,radix,isAlgorithmic,description); - cachedStringData.put(name, ns); - return ns; + return getInstance(name, radix, isAlgorithmic, description); } /** @@ -330,11 +340,22 @@ public class NumberingSystem { /** * Cache to hold the NumberingSystems by Locale. */ - private static ICUCache cachedLocaleData = new SimpleCache(); - + private static CacheBase cachedLocaleData = + new SoftCache() { + @Override + protected NumberingSystem createInstance(String key, LocaleLookupData localeLookupData) { + return lookupInstanceByLocale(localeLookupData); + } + }; + /** * Cache to hold the NumberingSystems by name. */ - private static ICUCache cachedStringData = new SimpleCache(); - + private static CacheBase cachedStringData = + new SoftCache() { + @Override + protected NumberingSystem createInstance(String key, Void unused) { + return lookupInstanceByName(key); + } + }; } -- 2.40.0