Class SoftCache<K,​V>

  • All Implemented Interfaces:
    java.util.Map<K,​V>

    public class SoftCache<K,​V>
    extends java.util.AbstractMap<K,​V>
    implements java.util.Map<K,​V>
    A memory-sensitive implementation of the Map interface.

    A SoftCache object uses soft references to implement a memory-sensitive hash map. If the garbage collector determines at a certain point in time that a value object in a SoftCache entry is no longer strongly reachable, then it may remove that entry in order to release the memory occupied by the value object. All SoftCache objects are guaranteed to be completely cleared before the virtual machine will throw an OutOfMemoryError. Because of this automatic clearing feature, the behavior of this class is somewhat different from that of other Map implementations.

    Both null values and the null key are supported. This class has the same performance characteristics as the HashMap class, and has the same efficiency parameters of initial capacity and load factor.

    Like most collection classes, this class is not synchronized. A synchronized SoftCache may be constructed using the Collections.synchronizedMap method.

    In typical usage this class will be subclassed and the fill method will be overridden. When the get method is invoked on a key for which there is no mapping in the cache, it will in turn invoke the fill method on that key in an attempt to construct a corresponding value. If the fill method returns such a value then the cache will be updated and the new value will be returned. Thus, for example, a simple URL-content cache can be constructed as follows:

         public class URLCache extends SoftCache {
             protected Object fill(Object key) {
                 return ((URL)key).getContent();
             }
         }
     

    The behavior of the SoftCache class depends in part upon the actions of the garbage collector, so several familiar (though not required) Map invariants do not hold for this class.

    Because entries are removed from a SoftCache in response to dynamic advice from the garbage collector, a SoftCache may behave as though an unknown thread is silently removing entries. In particular, even if you synchronize on a SoftCache instance and invoke none of its mutator methods, it is possible for the size method to return smaller values over time, for the isEmpty method to return false and then true, for the containsKey method to return true and later false for a given key, for the get method to return a value for a given key but later return null, for the put method to return null and the remove method to return false for a key that previously appeared to be in the map, and for successive examinations of the key set, the value set, and the entry set to yield successively smaller numbers of elements.

    I copied this from JDK 1.4.2 to avoid introducing another sun.misc dependency in the ORB. (Ken Cavanaugh)

    Since:
    JDK1.2
    Version:
    1.6, 03/01/23
    See Also:
    HashMap, SoftReference
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      private class  SoftCache.Entry  
      private class  SoftCache.EntrySet  
      private static class  SoftCache.ValueCell<K,​V>  
      • Nested classes/interfaces inherited from class java.util.AbstractMap

        java.util.AbstractMap.SimpleEntry<K extends java.lang.Object,​V extends java.lang.Object>, java.util.AbstractMap.SimpleImmutableEntry<K extends java.lang.Object,​V extends java.lang.Object>
    • Constructor Summary

      Constructors 
      Constructor Description
      SoftCache()
      Construct a new, empty SoftCache with the default capacity and the default load factor.
      SoftCache​(int initialCapacity)
      Construct a new, empty SoftCache with the given initial capacity and the default load factor.
      SoftCache​(int initialCapacity, float loadFactor)
      Construct a new, empty SoftCache with the given initial capacity and the given load factor.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void clear()
      Remove all mappings from this cache.
      boolean containsKey​(java.lang.Object key)
      Return true if this cache contains a mapping for the specified key.
      java.util.Set<java.util.Map.Entry<K,​V>> entrySet()
      Return a Set view of the mappings in this cache.
      protected V fill​(java.lang.Object key)
      Create a value object for the given key.
      V get​(java.lang.Object key)
      Return the value to which this cache maps the specified key.
      boolean isEmpty()
      Return true if this cache contains no key-value mappings.
      private void processQueue()  
      V put​(K key, V value)
      Update this cache so that the given key maps to the given value.
      V remove​(java.lang.Object key)
      Remove the mapping for the given key from this cache, if present.
      int size()
      Return the number of key-value mappings in this cache.
      private static boolean valEquals​(java.lang.Object o1, java.lang.Object o2)  
      • Methods inherited from class java.util.AbstractMap

        clone, containsValue, equals, hashCode, keySet, putAll, toString, values
      • Methods inherited from class java.lang.Object

        finalize, getClass, notify, notifyAll, wait, wait, wait
      • Methods inherited from interface java.util.Map

        compute, computeIfAbsent, computeIfPresent, containsValue, equals, forEach, getOrDefault, hashCode, keySet, merge, putAll, putIfAbsent, remove, replace, replace, replaceAll, values
    • Field Detail

      • PROCESS_QUEUE_INTERVAL

        private static final int PROCESS_QUEUE_INTERVAL
        See Also:
        Constant Field Values
      • processQueueCount

        private int processQueueCount
      • queue

        private java.lang.ref.ReferenceQueue<V> queue
      • entrySet

        private java.util.Set<java.util.Map.Entry<K,​V>> entrySet
    • Constructor Detail

      • SoftCache

        public SoftCache​(int initialCapacity,
                         float loadFactor)
        Construct a new, empty SoftCache with the given initial capacity and the given load factor.
        Parameters:
        initialCapacity - The initial capacity of the cache
        loadFactor - A number between 0.0 and 1.0
        Throws:
        java.lang.IllegalArgumentException - If the initial capacity is less than or equal to zero, or if the load factor is less than zero
      • SoftCache

        public SoftCache​(int initialCapacity)
        Construct a new, empty SoftCache with the given initial capacity and the default load factor.
        Parameters:
        initialCapacity - The initial capacity of the cache
        Throws:
        java.lang.IllegalArgumentException - If the initial capacity is less than or equal to zero
      • SoftCache

        public SoftCache()
        Construct a new, empty SoftCache with the default capacity and the default load factor.
    • Method Detail

      • processQueue

        private void processQueue()
      • size

        public int size()
        Return the number of key-value mappings in this cache. The time required by this operation is linear in the size of the map.
        Specified by:
        size in interface java.util.Map<K,​V>
        Overrides:
        size in class java.util.AbstractMap<K,​V>
      • isEmpty

        public boolean isEmpty()
        Return true if this cache contains no key-value mappings.
        Specified by:
        isEmpty in interface java.util.Map<K,​V>
        Overrides:
        isEmpty in class java.util.AbstractMap<K,​V>
      • containsKey

        public boolean containsKey​(java.lang.Object key)
        Return true if this cache contains a mapping for the specified key. If there is no mapping for the key, this method will not attempt to construct one by invoking the fill method.
        Specified by:
        containsKey in interface java.util.Map<K,​V>
        Overrides:
        containsKey in class java.util.AbstractMap<K,​V>
        Parameters:
        key - The key whose presence in the cache is to be tested
      • fill

        protected V fill​(java.lang.Object key)
        Create a value object for the given key. This method is invoked by the get method when there is no entry for key. If this method returns a non-null value, then the cache will be updated to map key to that value, and that value will be returned by the get method.

        The default implementation of this method simply returns null for every key value. A subclass may override this method to provide more useful behavior.

        Parameters:
        key - The key for which a value is to be computed
        Returns:
        A value for key, or null if one could not be computed
        See Also:
        get(java.lang.Object)
      • get

        public V get​(java.lang.Object key)
        Return the value to which this cache maps the specified key. If the cache does not presently contain a value for this key, then invoke the fill method in an attempt to compute such a value. If that method returns a non-null value, then update the cache and return the new value. Otherwise, return null.

        Note that because this method may update the cache, it is considered a mutator and may cause ConcurrentModificationExceptions to be thrown if invoked while an iterator is in use.

        Specified by:
        get in interface java.util.Map<K,​V>
        Overrides:
        get in class java.util.AbstractMap<K,​V>
        Parameters:
        key - The key whose associated value, if any, is to be returned
        See Also:
        fill(java.lang.Object)
      • put

        public V put​(K key,
                     V value)
        Update this cache so that the given key maps to the given value. If the cache previously contained a mapping for key then that mapping is replaced and the old value is returned.
        Specified by:
        put in interface java.util.Map<K,​V>
        Overrides:
        put in class java.util.AbstractMap<K,​V>
        Parameters:
        key - The key that is to be mapped to the given value
        value - The value to which the given key is to be mapped
        Returns:
        The previous value to which this key was mapped, or null if if there was no mapping for the key
      • remove

        public V remove​(java.lang.Object key)
        Remove the mapping for the given key from this cache, if present.
        Specified by:
        remove in interface java.util.Map<K,​V>
        Overrides:
        remove in class java.util.AbstractMap<K,​V>
        Parameters:
        key - The key whose mapping is to be removed
        Returns:
        The value to which this key was mapped, or null if there was no mapping for the key
      • clear

        public void clear()
        Remove all mappings from this cache.
        Specified by:
        clear in interface java.util.Map<K,​V>
        Overrides:
        clear in class java.util.AbstractMap<K,​V>
      • valEquals

        private static boolean valEquals​(java.lang.Object o1,
                                         java.lang.Object o2)
      • entrySet

        public java.util.Set<java.util.Map.Entry<K,​V>> entrySet()
        Return a Set view of the mappings in this cache.
        Specified by:
        entrySet in interface java.util.Map<K,​V>
        Specified by:
        entrySet in class java.util.AbstractMap<K,​V>