ICU-7434 cache region-to-Currency via SoftCache

X-SVN-Rev: 38739
This commit is contained in:
Markus Scherer 2016-05-13 23:31:36 +00:00
parent 220e261f82
commit fec331c017

View file

@ -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<ULocale, String> currencyCodeCache = new SimpleCache<ULocale, String>();
private static final SoftCache<String, Currency, Void> regionCurrencyCache =
new SoftCache<String, Currency, Void>() {
@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<String> 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);
}
} else {
return null;
}
currencyCodeCache.put(loc, code);
// 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 getInstance(code);
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<String> 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;
}
code = list.get(1);
}
return getInstance(code);
}
return null;
}
/**