ICU-7434 UResourceBundle ROOT_CACHE direct reference not SoftReference, change RootType from int to enum, remove hacky & obsolete resetBundleCache()

X-SVN-Rev: 38747
This commit is contained in:
Markus Scherer 2016-05-16 22:37:52 +00:00
parent 54b8f0c928
commit 0c24a0abdf
2 changed files with 23 additions and 77 deletions

View File

@ -7,12 +7,12 @@
package com.ibm.icu.util;
import java.lang.ref.SoftReference;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
@ -321,26 +321,6 @@ public abstract class UResourceBundle extends ResourceBundle {
private static ICUCache<ResourceCacheKey, UResourceBundle> BUNDLE_CACHE =
new SimpleCache<ResourceCacheKey, UResourceBundle>();
/**
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public static void resetBundleCache() {
/*
* A HACK!!!!!
* Currently if a resourcebundle with fallback turned ON is added to the cache
* and then a getBundleInstance() is called for a bundle with fallback turned OFF
* it will actually search the cache for any bundle of the same locale
* regaurdless of fallback status. This method has been created so that if
* The calling method KNOWS that instances of the other fallback state may be in the
* cache, the calling method may call this method to clear out the cache.
*
*/
//TODO figure a way around this method(see method comment)
BUNDLE_CACHE = new SimpleCache<ResourceCacheKey, UResourceBundle>();
}
/**
* Method used by subclasses to add a resource bundle object to the managed
* cache. Works like a putIfAbsent(): If the cache already contains a matching
@ -376,10 +356,10 @@ public abstract class UResourceBundle extends ResourceBundle {
/**
* Key used for cached resource bundles. The key checks
* the resource name, the class root, and the default
* the resource name and the default
* locale to determine if the resource is a match to the
* requested one. The root may be null, but the
* searchName and the default locale must have a non-null value.
* requested one. The default locale may be null, but the
* searchName must have a non-null value.
* Note that the default locale may change over time, and
* lookup should always be based on the current default
* locale (if at all).
@ -453,68 +433,36 @@ public abstract class UResourceBundle extends ResourceBundle {
private static final ResourceCacheKey cacheKey = new ResourceCacheKey();
private static final int ROOT_MISSING = 0;
private static final int ROOT_ICU = 1;
private static final int ROOT_JAVA = 2;
private enum RootType { MISSING, ICU, JAVA }
private static SoftReference<ConcurrentHashMap<String, Integer>> ROOT_CACHE =
new SoftReference<ConcurrentHashMap<String, Integer>>(new ConcurrentHashMap<String, Integer>());
private static Map<String, RootType> ROOT_CACHE = new ConcurrentHashMap<String, RootType>();
private static int getRootType(String baseName, ClassLoader root) {
ConcurrentHashMap<String, Integer> m = null;
Integer rootType;
m = ROOT_CACHE.get();
if (m == null) {
synchronized(UResourceBundle.class) {
m = ROOT_CACHE.get();
if (m == null) {
m = new ConcurrentHashMap<String, Integer>();
ROOT_CACHE = new SoftReference<ConcurrentHashMap<String, Integer>>(m);
}
}
}
rootType = m.get(baseName);
private static RootType getRootType(String baseName, ClassLoader root) {
RootType rootType = ROOT_CACHE.get(baseName);
if (rootType == null) {
String rootLocale = (baseName.indexOf('.')==-1) ? "root" : "";
int rt = ROOT_MISSING; // value set on success
try{
ICUResourceBundle.getBundleInstance(baseName, rootLocale, root, true);
rt = ROOT_ICU;
rootType = RootType.ICU;
}catch(MissingResourceException ex){
try{
ResourceBundleWrapper.getBundleInstance(baseName, rootLocale, root, true);
rt = ROOT_JAVA;
rootType = RootType.JAVA;
}catch(MissingResourceException e){
//throw away the exception
rootType = RootType.MISSING;
}
}
rootType = Integer.valueOf(rt);
m.putIfAbsent(baseName, rootType);
ROOT_CACHE.put(baseName, rootType);
}
return rootType.intValue();
return rootType;
}
private static void setRootType(String baseName, int rootType) {
Integer rt = Integer.valueOf(rootType);
ConcurrentHashMap<String, Integer> m = null;
m = ROOT_CACHE.get();
if (m == null) {
synchronized(UResourceBundle.class) {
m = ROOT_CACHE.get();
if (m == null) {
m = new ConcurrentHashMap<String, Integer>();
ROOT_CACHE = new SoftReference<ConcurrentHashMap<String, Integer>>(m);
}
}
}
m.put(baseName, rt);
private static void setRootType(String baseName, RootType rootType) {
ROOT_CACHE.put(baseName, rootType);
}
/**
@ -532,13 +480,12 @@ public abstract class UResourceBundle extends ResourceBundle {
protected static UResourceBundle instantiateBundle(String baseName, String localeName,
ClassLoader root, boolean disableFallback) {
UResourceBundle b = null;
int rootType = getRootType(baseName, root);
RootType rootType = getRootType(baseName, root);
ULocale defaultLocale = ULocale.getDefault();
switch (rootType)
{
case ROOT_ICU:
switch (rootType) {
case ICU:
if(disableFallback) {
String fullName = ICUResourceBundleReader.getFullName(baseName, localeName);
b = loadFromCache(fullName, defaultLocale);
@ -553,19 +500,20 @@ public abstract class UResourceBundle extends ResourceBundle {
return b;
case ROOT_JAVA:
case JAVA:
return ResourceBundleWrapper.getBundleInstance(baseName, localeName, root,
disableFallback);
case MISSING:
default:
try{
b = ICUResourceBundle.getBundleInstance(baseName, localeName, root,
disableFallback);
setRootType(baseName, ROOT_ICU);
setRootType(baseName, RootType.ICU);
}catch(MissingResourceException ex){
b = ResourceBundleWrapper.getBundleInstance(baseName, localeName, root,
disableFallback);
setRootType(baseName, ROOT_JAVA);
setRootType(baseName, RootType.JAVA);
}
return b;
}

View File

@ -1100,9 +1100,7 @@ public final class ICUResourceBundleTest extends TestFmwk {
}
rb7 = UResourceBundle.getBundleInstance("com.ibm.icu.dev.data.resources.TestDataElements", Locale.getDefault(), testLoader);
UResourceBundle.resetBundleCache();
try {
rb1.getBinary();
errln("getBinary() call should have thrown UResourceTypeMismatchException.");