mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-13 08:53:20 +00:00
ICU-7434 switch NumberingSystem from SimpleCache to SoftCache
X-SVN-Rev: 38743
This commit is contained in:
parent
677b1b1461
commit
3d7536e60b
1 changed files with 73 additions and 52 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
// Cache miss, create new instance
|
||||
// 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);
|
||||
}
|
||||
|
||||
String originalNumbersKeyword = numbersKeyword;
|
||||
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();
|
||||
}
|
||||
|
||||
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<String, NumberingSystem> cachedLocaleData = new SimpleCache<String, NumberingSystem>();
|
||||
|
||||
private static CacheBase<String, NumberingSystem, LocaleLookupData> cachedLocaleData =
|
||||
new SoftCache<String, NumberingSystem, LocaleLookupData>() {
|
||||
@Override
|
||||
protected NumberingSystem createInstance(String key, LocaleLookupData localeLookupData) {
|
||||
return lookupInstanceByLocale(localeLookupData);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Cache to hold the NumberingSystems by name.
|
||||
*/
|
||||
private static ICUCache<String, NumberingSystem> cachedStringData = new SimpleCache<String, NumberingSystem>();
|
||||
|
||||
private static CacheBase<String, NumberingSystem, Void> cachedStringData =
|
||||
new SoftCache<String, NumberingSystem, Void>() {
|
||||
@Override
|
||||
protected NumberingSystem createInstance(String key, Void unused) {
|
||||
return lookupInstanceByName(key);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue