blob: 04561cc877bbf19ef63de09bdfcdcab63ed3f889 [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.impl.locale;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
//public class LocaleObjectCache<K, V> {
public class LocaleObjectCache {
// private ConcurrentHashMap<K, WeakValueRef<V>> _map = new ConcurrentHashMap<K, WeakValueRef<V>>();
private Map _map = Collections.synchronizedMap(new HashMap());
// private ReferenceQueue<V> _rq = new ReferenceQueue<V>();
private ReferenceQueue _rq = new ReferenceQueue();
public LocaleObjectCache() {
}
// public V get(Object key) {
public Object get(Object key) {
expungeStaleEntries();
// WeakValueRef<V> ref = _map.get(key);
WeakValueRef ref = (WeakValueRef)_map.get(key);
if (ref != null) {
return ref.get();
}
return null;
}
/*
* Unlike Map#put, this method returns non-null value actually
* in the cache, even no values for the key was not available
* before.
*/
// public V put(K key, V value) {
public Object put(Object key, Object value) {
expungeStaleEntries();
// WeakValueRef<V> ref = _map.get(key);
WeakValueRef ref = (WeakValueRef)_map.get(key);
if (ref != null) {
// Make sure if another thread put the new value
// V valInCache = ref.get();
Object valInCache = (String)ref.get();
if (valInCache != null) {
return valInCache;
}
}
// We do not synchronize the internal map here.
// In the worst case, another thread may put the new
// value with the same contents, but it should not cause
// any serious problem.
// _map.put(key, new WeakValueRef<V>(key, value, _rq));
_map.put(key, new WeakValueRef(key, value, _rq));
return value;
}
private void expungeStaleEntries() {
// Reference<? extends V> val;
Reference val;
while ((val = _rq.poll()) != null) {
// Object key = ((WeakValueRef<?>)val).getKey();
Object key = ((WeakValueRef)val).getKey();
_map.remove(key);
}
}
// private static class WeakValueRef<V> extends WeakReference<V> {
private static class WeakValueRef extends WeakReference {
private Object _key;
// public WeakValueRef(Object key, V value, ReferenceQueue<V> rq) {
public WeakValueRef(Object key, Object value, ReferenceQueue rq) {
super(value, rq);
_key = key;
}
// public V get() {
public Object get() {
return super.get();
}
public Object getKey() {
return _key;
}
}
}