K
- The type of key objects.V
- The type of value objects.public class Cache<K,V> extends AbstractMap<K,V>
Callable
statement to be executed only if the object is not in the cache,
and to invoke the getOrCreate
method. Example:
An alternative is to perform explicitly all the steps enumerated above. This alternative avoid the creation of a temporaryprivate final Cache<String,MyObject> cache = new Cache<String,MyObject>(); public MyObject getMyObject(final String key) throws MyCheckedException { try { return cache.getOrCreate(key, new Callable<MyObject>() { MyObject call() throws FactoryException { return createMyObject(key); } }); } catch (MyCheckedException e) { throw e; } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new UndeclaredThrowableException(e); } }
Callable
statement which may never be executed,
and avoid the exception handling due to the throws Exception
clause. Note that the
call to putAndUnlock
must be in the finally
block of a try
block beginning immediately after the call to lock
,
no matter what the result of the computation is (including null
).
private final Cache<String,MyObject> cache = new Cache<String,MyObject>(); public MyObject getMyObject(final String key) throws MyCheckedException { MyObject value = cache.peek(key); if (value == null) { final Cache.Handler<MyObject> handler = cache.lock(key); try { value = handler.peek(); if (value == null) { value = createMyObject(key); } } finally { handler.putAndUnlock(value); } } return value; }
cost(V)
. The default
implementation returns 1 in all cases, but subclasses can override this method for
more elaborated cost computation.cost(V)
method has not been
overridden, then the total cost is the maximal amount of values to keep by strong references.
Defined in the sis-utility
module
Modifier and Type | Class and Description |
---|---|
static interface |
Cache.Handler<V>
The handler returned by
lock(K) , to be used for unlocking and storing the
result. |
AbstractMap.SimpleEntry<K,V>, AbstractMap.SimpleImmutableEntry<K,V>
Constructor and Description |
---|
Cache()
Creates a new cache with a default initial capacity and cost limit of 100.
|
Cache(int initialCapacity,
long costLimit,
boolean soft)
Creates a new cache using the given initial capacity and cost limit.
|
Modifier and Type | Method and Description |
---|---|
void |
clear()
Clears the content of this cache.
|
boolean |
containsKey(Object key)
Returns
true if this map contains the specified key. |
protected int |
cost(V value)
Computes an estimation of the cost of the given value.
|
Set<Map.Entry<K,V>> |
entrySet()
Returns the set of entries in this cache.
|
V |
get(Object key)
Returns the value associated to the given key in the cache.
|
V |
getOrCreate(K key,
Callable<? extends V> creator)
Returns the value for the given key.
|
boolean |
isEmpty()
Returns
true if this cache is empty. |
boolean |
isKeyCollisionAllowed()
Returns
true if different values may be assigned to the same key. |
Set<K> |
keySet()
Returns the set of keys in this cache.
|
Cache.Handler<V> |
lock(K key)
Gets a lock for the entry at the given key and returns a handler to be used by the caller
for unlocking and storing the result.
|
V |
peek(K key)
If a value is already cached for the given key, returns it.
|
V |
put(K key,
V value)
Puts the given value in cache.
|
V |
remove(Object key)
Removes the value associated to the given key in the cache.
|
void |
setKeyCollisionAllowed(boolean allowed)
If set to
true , different values may be assigned to the same key. |
int |
size()
Returns the number of elements in this cache.
|
clone, containsValue, equals, hashCode, putAll, toString, values
compute, computeIfAbsent, computeIfPresent, forEach, getOrDefault, merge, putIfAbsent, remove, replace, replace, replaceAll
public Cache()
public Cache(int initialCapacity, long costLimit, boolean soft)
The cost limit is the maximal value of the total cost (the sum of the cost of all values) before to replace eldest strong references by weak or soft references.
initialCapacity
- the initial capacity.costLimit
- The maximum number of objects to keep by strong reference.soft
- If true
, use SoftReference
instead of WeakReference
.public void clear()
public boolean isEmpty()
true
if this cache is empty.public int size()
public boolean containsKey(Object key)
true
if this map contains the specified key.containsKey
in interface Map<K,V>
containsKey
in class AbstractMap<K,V>
key
- The key to check for existence.true
if the given key still exist in this cache.public V get(Object key)
peek(K)
except that it blocks if the value is currently under computation in an
other thread.public V getOrCreate(K key, Callable<? extends V> creator) throws Exception
creator.call()
method is invoked and
its result is saved in this cache for future reuse.key
- The key for which to get the cached or created value.creator
- A method for creating a value, to be invoked only if no value are
cached for the given key.Exception
- If an exception occurred during the execution of creator.call()
.public V peek(K key)
null
.
This method is similar to get(Object)
except that it doesn't block if the value is
in process of being computed in an other thread; it returns null
in such case.key
- The key for which to get the cached value.null
if there is none.public Cache.Handler<V> lock(K key)
putAndUnlock
call in try
… catch
blocks as in the example below:
Cache.Handler handler = cache.lock(); try { // Compute the result... } finally { handler.putAndUnlock(result); }
key
- The key for the entry to lock.public Set<K> keySet()
ConcurrentHashMap.keySet()
method.public Set<Map.Entry<K,V>> entrySet()
ConcurrentHashMap.entrySet()
method, except that
it doesn't support removal of elements (including through the Iterator.remove()
method call).public boolean isKeyCollisionAllowed()
true
if different values may be assigned to the same key.
The default value is false
.true
if key collisions are allowed.public void setKeyCollisionAllowed(boolean allowed)
true
, different values may be assigned to the same key. This is usually an
error, so the default Cache
behavior is to thrown an IllegalStateException
in such cases, typically when Cache.Handler.putAndUnlock(Object)
is invoked. However in
some cases we may want to relax this check. For example the EPSG database sometime assigns
the same key to different kind of objects.
If key collisions are allowed and two threads invoke lock(Object)
concurrently
for the same key, then the value to be stored in the map will be the one computed by the
first thread who got the lock. The value computed by any other concurrent thread will be
ignored by this Cache
class. However those threads still return their computed
values to their callers.
This property can also be set in order to allow some recursivity. If during the creation
of an object, the program asks to this Cache
for the same object (using the same key),
then the default Cache
implementation will consider this situation as a key collision
unless this property has been set to true
.
allowed
- true
if key collisions should be allowed.protected int cost(V value)
value
- The object for which to get an estimation of its cost.Instrumentation.getObjectSize(Object)
Copyright © 2010–2015 The Apache Software Foundation. All rights reserved.