K
- the type of keys in the mapV
- the type of values in the mappublic class FastCache<K,V> extends AbstractMap<K,V> implements Serializable
FastCache
is a map implemented with soft references,
optimistic copy-on-write updates, and approximate count-based
pruning. It is intended for scalable multi-threaded caches. It
sacrifices recall of mappings for speed of put and get operations
along with conservative memory guarantees.
Note:The class HardFastCache
is nearly identical
to this class, but with no soft references around hash buckets.
The basis of the cache is a fixed-size hash map, based on values
returned by objects' hashCode()
and
equals(Object)
methods.
The map entries in the hash map are stored in buckets held by soft references. Thus entries in the mapping may be garbage collected. In the implementation, whole hash buckets are collected, which is safe and highly efficient but may require some additional recomputation of values that were removed by pruning.
Entries are stored in the map using a very optimistic update. No synchronization at all is performed on the cache entries or their counts. A copy-on-write strategy coupled with Java's memory model for references ensures that the cache remains consistent, if not complete. What this means is that multiple threads may both try to cache a mapping and only one will be saved and/or incremented in count.
When the table approximately exceeds the specified load factor,
the thread performing the add will perform a garbage collection by
reducing reference counts by half, rounding down, and removing
entries with zero counts. Pruning is subject to the caveats
mentioned in the last paragraph. Counts are not guaranteed to be
accurate. Pruning itself is synchronized and more conservatively
copy-on-write. By setting the load factor to
Double.POSITIVE_INFINITY
there will be never be any
pruning done by this class; all pruning will take place by soft
reference garbage collection.
A fast cache acts as a mapping with copy-on-write semantics. Equality and iteration are defined as usual, with the caveat that the snapshot taken of the elements may not be up to date. Iterators may be used concurrently, but their remove methods do not affect the underlying cache.
Serialization
A fast cache may be serialized if the keys and values it
contains are serializable. It may always be serialized if
it is first cleared using clear()
.
References
For more information on soft references, see:
AbstractMap.SimpleEntry<K,V>, AbstractMap.SimpleImmutableEntry<K,V>
Constructor and Description |
---|
FastCache(int size)
Constrcut a fast cache of the specified size and default load
factor.
|
FastCache(int size,
double loadFactor)
Construct a fast cache of the specified size (measured in
number of hash buckets) and load factor.
|
Modifier and Type | Method and Description |
---|---|
void |
clear()
Removes all entries from this cache.
|
Set<Map.Entry<K,V>> |
entrySet()
Returns a snapshot of the entries in this map.
|
V |
get(Object key)
Returns the value of the specified key or
null if
there is no value attached. |
void |
prune()
Prunes this cache by (approximately) dividing the counts of
entries by two and removing the ones with zero counts.
|
V |
put(K key,
V value)
Sets the value of the specified key to the specified value.
|
clone, containsKey, containsValue, equals, hashCode, isEmpty, keySet, putAll, remove, size, toString, values
finalize, getClass, notify, notifyAll, wait, wait, wait
compute, computeIfAbsent, computeIfPresent, forEach, getOrDefault, merge, putIfAbsent, remove, replace, replace, replaceAll
public FastCache(int size)
FastCache(int,double)
for more information.size
- Number of buckets in cacheIllegalArgumentException
- if the size is less than 2.public FastCache(int size, double loadFactor)
size
- Number of buckets in the cache.loadFactor
- Load factor of the cache.IllegalArgumentException
- If the size is less than one or the load
factor is not a positive finite value.public V get(Object key)
null
if
there is no value attached. Note that the argument is not
the generic <K>
key type, but Object
to match the requirements of java.util.Map
.
Warning: Because of the approximate cache-like
behavior of this class, key-value pairs previously added
by the put(Object,Object)
method may disappear.
public V put(K key, V value)
Warning: Because of the approximate cache-like
behavior of this class, setting the value of a key with this
method is not guaranteed to replace older values or remain in
the mapping until the next call to get(Object)
.
public void clear()
public void prune()