/* GENERATED SOURCE. DO NOT MODIFY. */
/*
*******************************************************************************
*   Copyright (C) 2010-2011, International Business Machines
*   Corporation and others.  All Rights Reserved.
*******************************************************************************
*/
package android.icu.impl;

import java.lang.ref.SoftReference;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Generic, thread-safe cache implementation, storing SoftReferences to cached instances.
 * To use, instantiate a subclass which implements the createInstance() method,
 * and call get() with the key and the data. The get() call will use the data
 * only if it needs to call createInstance(), otherwise the data is ignored.
 *
 * By using SoftReferences to instances, the Java runtime can release instances
 * once they are not used any more at all. If such an instance is then requested again,
 * the get() method will call createInstance() again and also create a new SoftReference.
 * The cache holds on to its map of keys to SoftReferenced instances forever.
 *
 * @param <K> Cache lookup key type
 * @param <V> Cache instance value type
 * @param <D> Data type for creating a new instance value
 *
 * @author Markus Scherer, Mark Davis
 * @hide Only a subset of ICU is exposed in Android
 * @hide All android.icu classes are currently hidden
 */
public abstract class SoftCache<K, V, D> extends CacheBase<K, V, D> {
    @Override
    public final V getInstance(K key, D data) {
        // We synchronize twice, once on the map and once on valueRef,
        // because we prefer the fine-granularity locking of the ConcurrentHashMap
        // over coarser locking on the whole cache instance.
        // We use a SettableSoftReference (a second level of indirection) because
        // ConcurrentHashMap.putIfAbsent() never replaces the key's value, and if it were
        // a simple SoftReference we would not be able to reset its value after it has been cleared.
        // (And ConcurrentHashMap.put() always replaces the value, which we don't want either.)
        SettableSoftReference<V> valueRef = map.get(key);
        V value;
        if(valueRef != null) {
            synchronized(valueRef) {
                value = valueRef.ref.get();
                if(value != null) {
                    return value;
                } else {
                    // The instance has been evicted, its SoftReference cleared.
                    // Create and set a new instance.
                    value = createInstance(key, data);
                    if (value != null) {
                        valueRef.ref = new SoftReference<V>(value);
                    }
                    return value;
                }
            }
        } else /* valueRef == null */ {
            // We had never cached an instance for this key.
            value = createInstance(key, data);
            if (value == null) {
                return null;
            }
            valueRef = map.putIfAbsent(key, new SettableSoftReference<V>(value));
            if(valueRef == null) {
                // Normal "put": Our new value is now cached.
                return value;
            } else {
                // Race condition: Another thread beat us to putting a SettableSoftReference
                // into the map. Return its value, but just in case the garbage collector
                // was aggressive, we also offer our new instance for caching.
                return valueRef.setIfAbsent(value);
            }
        }
    }
    /**
     * Value type for cache items: Has a SoftReference which can be set
     * to a new value when the SoftReference has been cleared.
     * The SoftCache class sometimes accesses the ref field directly.
     *
     * @param <V> Cache instance value type
     */
    private static final class SettableSoftReference<V> {
        private SettableSoftReference(V value) {
            ref = new SoftReference<V>(value);
        }
        /**
         * If the SoftReference has been cleared, then this replaces it with a new SoftReference
         * for the new value and returns the new value; otherwise returns the current
         * SoftReference's value.
         * @param value Replacement value, for when the current reference has been cleared
         * @return The value that is held by the SoftReference, old or new
         */
        private synchronized V setIfAbsent(V value) {
            V oldValue = ref.get();
            if(oldValue == null) {
                ref = new SoftReference<V>(value);
                return value;
            } else {
                return oldValue;
            }
        }
        private SoftReference<V> ref;  // never null
    }
    private ConcurrentHashMap<K, SettableSoftReference<V>> map =
        new ConcurrentHashMap<K, SettableSoftReference<V>>();
}
