Top Description Inners Fields Constructors Methods
org.glassfish.hk2.utilities.cache

public Class LRUHybridCache<K, V>

extends Object
implements Computable<K, HybridCacheEntry<V>>
Class Inheritance
All Implemented Interfaces
org.glassfish.hk2.utilities.cache.Computable
Type Parameters
<K>
The type for the keys in the cache
<V>
The type for the values in the cache
Imports
java.util.Collection, .Collections, .Comparator, java.util.concurrent.Callable, .ConcurrentHashMap, .ExecutionException, .Future, .FutureTask, .TimeUnit, .TimeoutException, java.util.concurrent.locks.ReentrantLock

Hybrid cache that allows explicit removals of included entries as well as implicit removal of entries that have been least recently accessed. The implicit removal happens only in case the internal cache runs out of space. Maximum number of items that can be kept in the cache is invariant for a single cache instance, and can be set in the cache constructor. The cache deals with HybridCacheEntry items than could even instruct the cache to drop them as they get computed. The cache will still make sure such items get computed just once in given time (based on computation length) for given key. Desired value will only be computed once and computed value stored in the cache. The implementation is based on an example from the "Java Concurrency in Practice" book authored by Brian Goetz and company.
Author
Jakub Podlesak (jakub.podlesak at oracle.com)

Nested and Inner Type Summary

Modifier and TypeClass and Description
private static class
public static interface
LRUHybridCache.CycleHandler<
Key type.
K
>

Should a cycle be detected during computation of a value for given key, this interface allows client code to register a callback that would get invoked in such a case.

private class
private class
LRUHybridCache.OriginThreadAwareFuture

Helper class, that remembers the future task origin thread, so that cycles could be detected.

Field Summary

Modifier and TypeField and Description
private final ConcurrentHashMap<K, LRUHybridCache<K, V>.OriginThreadAwareFuture>
private static final Comparator<LRUHybridCache.OriginThreadAwareFuture>
private final Computable<K, HybridCacheEntry<V>>
private final LRUHybridCache.CycleHandler<K>
private static final LRUHybridCache.CycleHandler<Object>
private final int
private final ReentrantLock

Constructor Summary

AccessConstructor and Description
public
LRUHybridCache(int
The maximum number of entries in the cache
maxCacheSize
,
Computable<K, HybridCacheEntry<V>>
The thing that can create the entry
computable
)

Create new cache with given computable to compute values.

public
LRUHybridCache(int
The maximum number of entries in the cache
maxCacheSize
,
Computable<K, HybridCacheEntry<V>>
The thing that can create the entry
computable
,
LRUHybridCache.CycleHandler<K>
What to do if a cycle is detected
cycleHandler
)

Create new cache with given computable and cycleHandler.

Method Summary

Modifier and TypeMethod and Description
public void
clear()

Empty the cache.

public HybridCacheEntry<V>
compute(final K key)

Implements org.glassfish.hk2.utilities.cache.Computable.compute.

Defines an expensive computation to retrieve value V from key K.

public boolean

Returns:

true if given key is present in the cache.
containsKey
(final K key)

Returns true if the key has already been cached.

public HybridCacheEntry<V>

Returns:

an instance of cache entry.
createCacheEntry
(final K
cache entry key.
k
,
final V
cache entry value.
v
,
final boolean
should this entry be kept in the cache this must be set to false.
dropMe
)

Create cache entry for given values.

public int
public void
releaseMatching(CacheKeyFilter<K>
Entries in the cache that match this filter will be removed from the cache. If filter is null nothing will be removed from the cache
filter
)

This method will remove all cache entries for which this filter matches

public void
remove(final K
item key.
key
)

Remove given item from the cache.

private void
removeLRUItem()

Remove least recently used item form the cache.

public int

Returns:

The current size of the cache
size
()

Return the size of the cache

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

cacheback to summary
private final ConcurrentHashMap<K, LRUHybridCache<K, V>.OriginThreadAwareFuture> cache
COMPARATORback to summary
private static final Comparator<LRUHybridCache.OriginThreadAwareFuture> COMPARATOR
computableback to summary
private final Computable<K, HybridCacheEntry<V>> computable
cycleHandlerback to summary
private final LRUHybridCache.CycleHandler<K> cycleHandler
EMPTY_CYCLE_HANDLERback to summary
private static final LRUHybridCache.CycleHandler<Object> EMPTY_CYCLE_HANDLER
maxCacheSizeback to summary
private final int maxCacheSize
prunningLockback to summary
private final ReentrantLock prunningLock

Constructor Detail

LRUHybridCacheback to summary
public LRUHybridCache(int maxCacheSize, Computable<K, HybridCacheEntry<V>> computable)

Create new cache with given computable to compute values.

Parameters
maxCacheSize:int

The maximum number of entries in the cache

computable:Computable<K, HybridCacheEntry<V>>

The thing that can create the entry

Annotations
@SuppressWarnings:unchecked
LRUHybridCacheback to summary
public LRUHybridCache(int maxCacheSize, Computable<K, HybridCacheEntry<V>> computable, LRUHybridCache.CycleHandler<K> cycleHandler)

Create new cache with given computable and cycleHandler.

Parameters
maxCacheSize:int

The maximum number of entries in the cache

computable:Computable<K, HybridCacheEntry<V>>

The thing that can create the entry

cycleHandler:LRUHybridCache.CycleHandler<K>

What to do if a cycle is detected

Method Detail

clearback to summary
public void clear()

Empty the cache.

computeback to summary
public HybridCacheEntry<V> compute(final K key)

Implements org.glassfish.hk2.utilities.cache.Computable.compute.

Doc from org.glassfish.hk2.utilities.cache.Computable.compute.

Defines an expensive computation to retrieve value V from key K.

Annotations
@Override
containsKeyback to summary
public boolean containsKey(final K key)

Returns true if the key has already been cached.

Returns:boolean

true if given key is present in the cache.

createCacheEntryback to summary
public HybridCacheEntry<V> createCacheEntry(final K k, final V v, final boolean dropMe)

Create cache entry for given values.

Parameters
k:K

cache entry key.

v:V

cache entry value.

dropMe:boolean

should this entry be kept in the cache this must be set to false.

Returns:HybridCacheEntry<V>

an instance of cache entry.

getMaximumCacheSizeback to summary
public int getMaximumCacheSize()
releaseMatchingback to summary
public void releaseMatching(CacheKeyFilter<K> filter)

This method will remove all cache entries for which this filter matches

Parameters
filter:CacheKeyFilter<K>

Entries in the cache that match this filter will be removed from the cache. If filter is null nothing will be removed from the cache

removeback to summary
public void remove(final K key)

Remove given item from the cache.

Parameters
key:K

item key.

removeLRUItemback to summary
private void removeLRUItem()

Remove least recently used item form the cache. No checks are done here. The method just tries to remove the least recently used cache item. An exception will be thrown if the cache is empty.

sizeback to summary
public int size()

Return the size of the cache

Returns:int

The current size of the cache

org.glassfish.hk2.utilities.cache back to summary

private Class LRUHybridCache.CacheEntryImplComparator<K, V>

extends Object
implements Comparator<LRUHybridCache<K, V>.OriginThreadAwareFuture>
Class Inheritance
  • java.lang.Object
  • org.glassfish.hk2.utilities.cache.LRUHybridCache.CacheEntryImplComparator
All Implemented Interfaces
java.util.Comparator

Constructor Summary

AccessConstructor and Description
private

Method Summary

Modifier and TypeMethod and Description
public int
compare(LRUHybridCache<K, V>.OriginThreadAwareFuture first, LRUHybridCache<K, V>.OriginThreadAwareFuture second)

Implements java.util.Comparator.compare.

Compares its two arguments for order.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Constructor Detail

CacheEntryImplComparatorback to summary
private CacheEntryImplComparator()

Method Detail

compareback to summary
public int compare(LRUHybridCache<K, V>.OriginThreadAwareFuture first, LRUHybridCache<K, V>.OriginThreadAwareFuture second)

Implements java.util.Comparator.compare.

Doc from java.util.Comparator.compare.

Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.

The implementor must ensure that signum(compare(x, y)) == -signum(compare(y, x)) for all x and y. (This implies that compare(x, y) must throw an exception if and only if compare(y, x) throws an exception.)

The implementor must also ensure that the relation is transitive: ((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.

Finally, the implementor must ensure that compare(x, y)==0 implies that signum(compare(x, z))==signum(compare(y, z)) for all z.

Annotations
@Override
org.glassfish.hk2.utilities.cache back to summary

public Interface LRUHybridCache.CycleHandler<K>

Type Parameters
<K>
Key type.

Should a cycle be detected during computation of a value for given key, this interface allows client code to register a callback that would get invoked in such a case. The cycle is defined as follows. If any thread starts computation for given key and code from the very same thread requests the computed value before the computation ends, a cycle is detected. Registered cycle handler is then given a chance to handle the cycle and throw a runtime exception if appropriate.

Method Summary

Modifier and TypeMethod and Description
public void
handleCycle(K
instance that caused the cycle.
key
)

Handle cycle that was detected while computing a cache value for given key.

Method Detail

handleCycleback to summary
public void handleCycle(K key)

Handle cycle that was detected while computing a cache value for given key. This method would typically just throw a runtime exception.

Parameters
key:K

instance that caused the cycle.

org.glassfish.hk2.utilities.cache back to summary

private final Class LRUHybridCache.HybridCacheEntryImpl<V1>

extends Object
implements HybridCacheEntry<V1>
Class Inheritance
  • java.lang.Object
  • org.glassfish.hk2.utilities.cache.LRUHybridCache.HybridCacheEntryImpl
All Implemented Interfaces
org.glassfish.hk2.utilities.cache.HybridCacheEntry, org.glassfish.hk2.utilities.cache.CacheEntry

Field Summary

Modifier and TypeField and Description
private final boolean
private final K
private final V1

Constructor Summary

AccessConstructor and Description
public
HybridCacheEntryImpl(K key, V1 value, boolean dropMe)

Method Summary

Modifier and TypeMethod and Description
public boolean
dropMe()

Implements org.glassfish.hk2.utilities.cache.HybridCacheEntry.dropMe.

Tell the cache if this entry should be dropped as opposed to being kept in the cache.

public boolean
equals(Object obj)

Overrides java.lang.Object.equals.

Indicates whether some other object is "equal to" this one.

public V1
getValue()

Implements org.glassfish.hk2.utilities.cache.HybridCacheEntry.getValue.

Getter for this cache entry internal value.

public int
hashCode()

Overrides java.lang.Object.hashCode.

Returns a hash code value for this object.

public void
removeFromCache()

Implements org.glassfish.hk2.utilities.cache.CacheEntry.removeFromCache.

Call this method on this entry to remove it from the LRUCache.

Inherited from java.lang.Object:
clonefinalizegetClassnotifynotifyAlltoStringwaitwaitwait

Field Detail

dropMeback to summary
private final boolean dropMe
keyback to summary
private final K key
valueback to summary
private final V1 value

Constructor Detail

HybridCacheEntryImplback to summary
public HybridCacheEntryImpl(K key, V1 value, boolean dropMe)

Method Detail

dropMeback to summary
public boolean dropMe()

Implements org.glassfish.hk2.utilities.cache.HybridCacheEntry.dropMe.

Doc from org.glassfish.hk2.utilities.cache.HybridCacheEntry.dropMe.

Tell the cache if this entry should be dropped as opposed to being kept in the cache.

Annotations
@Override
equalsback to summary
public boolean equals(Object obj)

Overrides java.lang.Object.equals.

Doc from java.lang.Object.equals.

Indicates whether some other object is "equal to" this one.

The equals method implements an equivalence relation on non-null object references:

  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.
  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
  • For any non-null reference value x, x.equals(null) should return false.

An equivalence relation partitions the elements it operates on into equivalence classes; all the members of an equivalence class are equal to each other. Members of an equivalence class are substitutable for each other, at least for some purposes.

Annotations
@SuppressWarnings:unchecked
@Override
getValueback to summary
public V1 getValue()

Implements org.glassfish.hk2.utilities.cache.HybridCacheEntry.getValue.

Doc from org.glassfish.hk2.utilities.cache.HybridCacheEntry.getValue.

Getter for this cache entry internal value.

Annotations
@Override
hashCodeback to summary
public int hashCode()

Overrides java.lang.Object.hashCode.

Doc from java.lang.Object.hashCode.

Returns a hash code value for this object. This method is supported for the benefit of hash tables such as those provided by java.util.HashMap.

The general contract of hashCode is:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
Annotations
@Override
removeFromCacheback to summary
public void removeFromCache()

Implements org.glassfish.hk2.utilities.cache.CacheEntry.removeFromCache.

Doc from org.glassfish.hk2.utilities.cache.CacheEntry.removeFromCache.

Call this method on this entry to remove it from the LRUCache. If this entry has already been removed this method will do nothing.

Annotations
@Override
org.glassfish.hk2.utilities.cache back to summary

private Class LRUHybridCache.OriginThreadAwareFuture

extends Object
implements Future<HybridCacheEntry<V>>
Class Inheritance
  • java.lang.Object
  • org.glassfish.hk2.utilities.cache.LRUHybridCache.OriginThreadAwareFuture
All Implemented Interfaces
java.util.concurrent.Future

Helper class, that remembers the future task origin thread, so that cycles could be detected.

Field Summary

Modifier and TypeField and Description
private final FutureTask<HybridCacheEntry<V>>
private final K
private volatile long
private volatile long

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
public boolean
cancel(boolean mayInterruptIfRunning)

Implements java.util.concurrent.Future.cancel.

Attempts to cancel execution of this task.

public boolean
equals(Object obj)

Overrides java.lang.Object.equals.

Indicates whether some other object is "equal to" this one.

public HybridCacheEntry<V>
get()

Implements java.util.concurrent.Future.get.

Waits if necessary for the computation to complete, and then retrieves its result.

public HybridCacheEntry<V>
get(long timeout, TimeUnit unit)

Implements java.util.concurrent.Future.get.

Waits if necessary for at most the given time for the computation to complete, and then retrieves its result, if available.

public int
hashCode()

Overrides java.lang.Object.hashCode.

Returns a hash code value for this object.

public boolean
isCancelled()

Implements java.util.concurrent.Future.isCancelled.

Returns true if this task was cancelled before it completed normally.

public boolean
isDone()

Implements java.util.concurrent.Future.isDone.

Returns true if this task completed.

public void
run()

Inherited from java.lang.Object:
clonefinalizegetClassnotifynotifyAlltoStringwaitwaitwait

Field Detail

futureback to summary
private final FutureTask<HybridCacheEntry<V>> future
keyback to summary
private final K key
lastHitback to summary
private volatile long lastHit
threadIdback to summary
private volatile long threadId

Constructor Detail

OriginThreadAwareFutureback to summary
pack-priv OriginThreadAwareFuture(LRUHybridCache<K, HybridCacheEntry<V>> cache, final K key)

Method Detail

cancelback to summary
public boolean cancel(boolean mayInterruptIfRunning)

Implements java.util.concurrent.Future.cancel.

Doc from java.util.concurrent.Future.cancel.

Attempts to cancel execution of this task. This method has no effect if the task is already completed or cancelled, or could not be cancelled for some other reason. Otherwise, if this task has not started when cancel is called, this task should never run. If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task (when known by the implementation) is interrupted in an attempt to stop the task.

The return value from this method does not necessarily indicate whether the task is now cancelled; use isCancelled.

Annotations
@Override
equalsback to summary
public boolean equals(Object obj)

Overrides java.lang.Object.equals.

Doc from java.lang.Object.equals.

Indicates whether some other object is "equal to" this one.

The equals method implements an equivalence relation on non-null object references:

  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.
  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
  • For any non-null reference value x, x.equals(null) should return false.

An equivalence relation partitions the elements it operates on into equivalence classes; all the members of an equivalence class are equal to each other. Members of an equivalence class are substitutable for each other, at least for some purposes.

Annotations
@SuppressWarnings:unchecked, rawtypes
@Override
getback to summary
public HybridCacheEntry<V> get() throws InterruptedException, ExecutionException

Implements java.util.concurrent.Future.get.

Doc from java.util.concurrent.Future.get.

Waits if necessary for the computation to complete, and then retrieves its result.

Annotations
@Override
Exceptions
InterruptedException:
if the current thread was interrupted while waiting
ExecutionException:
if the computation threw an exception
getback to summary
public HybridCacheEntry<V> get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException

Implements java.util.concurrent.Future.get.

Doc from java.util.concurrent.Future.get.

Waits if necessary for at most the given time for the computation to complete, and then retrieves its result, if available.

Annotations
@Override
Exceptions
InterruptedException:
if the current thread was interrupted while waiting
ExecutionException:
if the computation threw an exception
TimeoutException:
if the wait timed out
hashCodeback to summary
public int hashCode()

Overrides java.lang.Object.hashCode.

Doc from java.lang.Object.hashCode.

Returns a hash code value for this object. This method is supported for the benefit of hash tables such as those provided by java.util.HashMap.

The general contract of hashCode is:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
Annotations
@Override
isCancelledback to summary
public boolean isCancelled()

Implements java.util.concurrent.Future.isCancelled.

Doc from java.util.concurrent.Future.isCancelled.

Returns true if this task was cancelled before it completed normally.

Annotations
@Override
isDoneback to summary
public boolean isDone()

Implements java.util.concurrent.Future.isDone.

Doc from java.util.concurrent.Future.isDone.

Returns true if this task completed. Completion may be due to normal termination, an exception, or cancellation -- in all of these cases, this method will return true.

Annotations
@Override
runback to summary
public void run()