jdbm.helper

## Class SoftCache

- java.lang.Object
- - jdbm.helper.SoftCache

All Implemented Interfaces:
  CachePolicy

    public class SoftCache
    extends Object
    implements CachePolicy

Wraps a deterministic cache policy with a Level-2 cache based on J2SE's `soft references`. Soft references allow this cache to keep references to objects until the memory they occupy is required elsewhere.

Since the `CachePolicy` interface requires an event be fired when an object is evicted, and the event contains the actual object, this class cannot be a stand-alone implementation of `CachePolicy`. This limitation arises because Java References does not support notification before references are cleared; nor do they support reaching soft referents. Therefore, this wrapper cache aggressively notifies evictions: events are fired when the objects are evicted from the internal cache. Consequently, the soft cache may return a non-null object when `get( )` is called, even if that object was said to have been evicted.

The current implementation uses a hash structure for its internal key to value mappings.

Note: this component's publicly exposed methods are not threadsafe; potentially concurrent code should synchronize on the cache instance.

Author:
  Dilum Ranatunga

### Constructor Summary

Constructors
Constructor and Description
`SoftCache()` Creates a soft-reference based L2 cache with a `MRU` cache as the internal (L1) cache.
`SoftCache(CachePolicy internal)` Creates a soft-reference based L2 cache wrapping the specified L1 cache.
`SoftCache(float loadFactor, CachePolicy internal)` Creates a soft-reference based L2 cache wrapping the specified L1 cache.

### Method Summary

Methods
`void` `addListener(CachePolicyListener listener)` Adds the specified listener to this cache.
`Enumeration` `elements()` Gets all the objects stored by the internal (L1) cache.
`Object` `get(Object key)` Gets the object cached under the specified key.
`void` `put(Object key, Object value)` Adds the specified value to the cache under the specified key.
`void` `remove(Object key)` Removes any object stored under the key specified.
`void` `removeAll()` Removes all objects in this (L2) and its internal (L1) cache.
`void` `removeListener(CachePolicyListener listener)` Removes a listener that was added earlier.

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Constructor Detail

#### SoftCache

    public SoftCache()

Creates a soft-reference based L2 cache with a `MRU` cache as the internal (L1) cache. The soft reference cache uses the default load capacity of 1.5f, which is intended to sacrifice some performance for space. This compromise is reasonable, since all `get( )s` first try the L1 cache anyway. The internal MRU is given a capacity of 128 elements.

#### SoftCache

    public SoftCache(CachePolicy internal)
              throws NullPointerException

Creates a soft-reference based L2 cache wrapping the specified L1 cache.

Parameters:
  `internal` - non null internal cache.
Throws:
  `NullPointerException` - if the internal cache is null.

#### SoftCache

    public SoftCache(float loadFactor,
             CachePolicy internal)
              throws IllegalArgumentException,
                     NullPointerException

Creates a soft-reference based L2 cache wrapping the specified L1 cache. This constructor is somewhat implementation-specific, so users are encouraged to use `SoftCache(CachePolicy)` instead.

Parameters:
  `loadFactor` - load factor that the soft cache's hash structure should use.
  `internal` - non null internal cache.
Throws:
  `IllegalArgumentException` - if the load factor is nonpositive.
  `NullPointerException` - if the internal cache is null.

### Method Detail

#### put

    public void put(Object key,
           Object value)
             throws CacheEvictionException

Adds the specified value to the cache under the specified key. Note that the object is added to both this and the internal cache.

Specified by:
  `put` in interface `CachePolicy`
Parameters:
  `key` - the (non-null) key to store the object under
  `value` - the (non-null) object to place in the cache
Throws:
  `CacheEvictionException` - exception that the internal cache would have experienced while evicting an object it currently cached.

#### get

    public Object get(Object key)

Gets the object cached under the specified key.

The cache is looked up in the following manner:

1. The internal (L1) cache is checked. If the object is found, it is returned.
2. This (L2) cache is checked. If the object is not found, then the caller is informed that the object is inaccessible.
3. Since the object exists in L2, but not in L1, the object is readded to L1 using `CachePolicy.put(Object, Object)`.
4. If the readding succeeds, the value is returned to caller.
5. If a cache eviction exception is encountered instead, we remove the object from L2 and behave as if the object was inaccessible.

Specified by:
  `get` in interface `CachePolicy`
Parameters:
  `key` - the key that the object was stored under.
Returns:
  the object stored under the key specified; null if the object is not (nolonger) accessible via this cache.

#### remove

    public void remove(Object key)

Removes any object stored under the key specified. Note that the object is removed from both this (L2) and the internal (L1) cache.

Specified by:
  `remove` in interface `CachePolicy`
Parameters:
  `key` - the key whose object should be removed

#### removeAll

    public void removeAll()

Removes all objects in this (L2) and its internal (L1) cache.

Specified by:
  `removeAll` in interface `CachePolicy`

#### elements

    public Enumeration elements()

Gets all the objects stored by the internal (L1) cache.

Specified by:
  `elements` in interface `CachePolicy`
Returns:
  an enumeration of objects in internal cache.

#### addListener

    public void addListener(CachePolicyListener listener)
                     throws IllegalArgumentException

Adds the specified listener to this cache. Note that the events fired by this correspond to the internal cache's events.

Specified by:
  `addListener` in interface `CachePolicy`
Parameters:
  `listener` - the (non-null) listener to add to this policy
Throws:
  `IllegalArgumentException` - if listener is null.

#### removeListener

    public void removeListener(CachePolicyListener listener)

Removes a listener that was added earlier.

Specified by:
  `removeListener` in interface `CachePolicy`
Parameters:
  `listener` - the listener to remove.