From fec331c0173cb773acda0fad03479a01df921483 Mon Sep 17 00:00:00 2001 From: Markus Scherer Date: Fri, 13 May 2016 23:31:36 +0000 Subject: [PATCH] ICU-7434 cache region-to-Currency via SoftCache X-SVN-Rev: 38739 --- .../core/src/com/ibm/icu/util/Currency.java | 61 ++++++++++++------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/icu4j/main/classes/core/src/com/ibm/icu/util/Currency.java b/icu4j/main/classes/core/src/com/ibm/icu/util/Currency.java index c8205b4d102..e3a8f0a2432 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/util/Currency.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/util/Currency.java @@ -26,6 +26,7 @@ import com.ibm.icu.impl.ICUData; import com.ibm.icu.impl.ICUDebug; import com.ibm.icu.impl.ICUResourceBundle; import com.ibm.icu.impl.SimpleCache; +import com.ibm.icu.impl.SoftCache; import com.ibm.icu.impl.TextTrieMap; import com.ibm.icu.text.CurrencyDisplayNames; import com.ibm.icu.text.CurrencyMetaInfo; @@ -228,39 +229,55 @@ public class Currency extends MeasureUnit { } private static final String EUR_STR = "EUR"; - private static final ICUCache currencyCodeCache = new SimpleCache(); - + private static final SoftCache regionCurrencyCache = + new SoftCache() { + @Override + protected Currency createInstance(String key, Void unused) { + return loadCurrency(key); + } + }; + /** * Instantiate a currency from resource data. */ /* package */ static Currency createCurrency(ULocale loc) { - String variant = loc.getVariant(); if ("EURO".equals(variant)) { return getInstance(EUR_STR); } - - String code = currencyCodeCache.get(loc); - if (code == null) { - String country = ULocale.getRegionForSupplementalData(loc, false); - - CurrencyMetaInfo info = CurrencyMetaInfo.getInstance(); - List list = info.currencies(CurrencyFilter.onRegion(country)); - if (list.size() > 0) { - code = list.get(0); - boolean isPreEuro = "PREEURO".equals(variant); - if (isPreEuro && EUR_STR.equals(code)) { - if (list.size() < 2) { - return null; - } - code = list.get(1); + + // Cache the currency by region, and whether variant=PREEURO. + // Minimizes the size of the cache compared with caching by ULocale. + String key = ULocale.getRegionForSupplementalData(loc, false); + if ("PREEURO".equals(variant)) { + key = key + '-'; + } + return regionCurrencyCache.getInstance(key, null); + } + + private static Currency loadCurrency(String key) { + String region; + boolean isPreEuro; + if (key.endsWith("-")) { + region = key.substring(0, key.length() - 1); + isPreEuro = true; + } else { + region = key; + isPreEuro = false; + } + CurrencyMetaInfo info = CurrencyMetaInfo.getInstance(); + List list = info.currencies(CurrencyFilter.onRegion(region)); + if (!list.isEmpty()) { + String code = list.get(0); + if (isPreEuro && EUR_STR.equals(code)) { + if (list.size() < 2) { + return null; } - } else { - return null; + code = list.get(1); } - currencyCodeCache.put(loc, code); + return getInstance(code); } - return getInstance(code); + return null; } /** -- 2.40.0