A scan resistant cache. It is meant to cache objects that are relatively
costly to acquire, for example file content.
This implementation is multi-threading safe and supports concurrent access.
Null keys or null values are not allowed. The map fill factor is at most 75%.
Each entry is assigned a distinct memory size, and the cache will try to use
at most the specified amount of memory. The memory unit is not relevant,
however it is suggested to use bytes as the unit.
This class implements an approximation of the the LIRS replacement algorithm
invented by Xiaodong Zhang and Song Jiang as described in
http://www.cse.ohio-state.edu/~zhang/lirs-sigmetrics-02.html with a few
smaller changes: An additional queue for non-resident entries is used, to
prevent unbound memory usage. The maximum size of this queue is at most the
size of the rest of the stack. About 6.25% of the mapped entries are cold.
Internally, the cache is split into a number of segments, and each segment is
an individual LIRS cache.
Accessed entries are only moved to the top of the stack if at least a number
of other entries have been moved to the front (8 per segment by default).
Write access and moving entries to the top of the stack is synchronized per
segment.
| Methods |
| static int |
getHash(Object key)
Get the hash code for the given key.
|
| static int |
getHash(Object key)
Get the hash code for the given key. The hash code is
further enhanced to spread the values more evenly.
Parameters:
key - the key
Returns:
the hash code
|
|
CacheLIRS(long maxMemory)
Create a new cache with the given number of entries, and the default
settings (16 segments, and stack move distance of 8.
|
|
CacheLIRS(long maxMemory)
Create a new cache with the given number of entries, and the default
settings (16 segments, and stack move distance of 8.
Parameters:
maxMemory - the maximum memory to use (1 or larger)
|
|
CacheLIRS(long maxMemory, int segmentCount, int stackMoveDistance)
Create a new cache with the given memory size.
|
|
CacheLIRS(long maxMemory, int segmentCount, int stackMoveDistance)
Create a new cache with the given memory size.
Parameters:
maxMemory - the maximum memory to use (1 or larger)
segmentCount - the number of cache segments (must be a power of 2)
stackMoveDistance - how many other item are to be moved to the top
of the stack before the current item is moved
|
| void |
clear()
Remove all entries.
|
| void |
clear()
Remove all entries.
|
| boolean |
containsKey(Object key)
Check whether there is a resident entry for the given key.
|
| boolean |
containsKey(Object key)
Check whether there is a resident entry for the given key. This
method does not adjust the internal state of the cache.
Parameters:
key - the key (may not be null)
Returns:
true if there is a resident entry
|
| Set |
entrySet()
Get the entry set for all resident entries.
|
| Set |
entrySet()
Get the entry set for all resident entries.
Returns:
the entry set
|
| V |
get(Object key)
Get the value for the given key if the entry is cached.
|
| V |
get(Object key)
Get the value for the given key if the entry is cached. This method
adjusts the internal state of the cache sometimes, to ensure commonly
used entries stay in the cache.
Parameters:
key - the key (may not be null)
Returns:
the value, or null if there is no resident entry
|
| long |
getMaxMemory()
Get the maximum memory to use.
|
| long |
getMaxMemory()
Get the maximum memory to use.
Returns:
the maximum memory
|
| int |
getMemory(K key)
Get the memory used for the given key.
|
| int |
getMemory(K key)
Get the memory used for the given key.
Parameters:
key - the key (may not be null)
Returns:
the memory, or 0 if there is no resident entry
|
| long |
getUsedMemory()
Get the currently used memory.
|
| long |
getUsedMemory()
Get the currently used memory.
Returns:
the used memory
|
| Set |
keySet()
Get the set of keys for resident entries.
|
| Set |
keySet()
Get the set of keys for resident entries.
Returns:
the set of keys
|
| List |
keys(boolean cold, boolean nonResident)
Get the list of keys.
|
| List |
keys(boolean cold, boolean nonResident)
Get the list of keys. This method allows to read the internal state of
the cache.
Parameters:
cold - if true, only keys for the cold entries are returned
nonResident - true for non-resident entries
Returns:
the key list
|
| void |
onRemove(K key)
This method is called after the value for the given key was removed.
|
| void |
onRemove(K key)
This method is called after the value for the given key was removed.
It is not called on clear or put when replacing a value.
Parameters:
key - the key
|
| V |
peek(K key)
Get the value for the given key if the entry is cached.
|
| V |
peek(K key)
Get the value for the given key if the entry is cached. This method does
not modify the internal state.
Parameters:
key - the key (may not be null)
Returns:
the value, or null if there is no resident entry
|
| V |
put(K key, V value, int memory)
Add an entry to the cache.
|
| V |
put(K key, V value, int memory)
Add an entry to the cache. The entry may or may not exist in the
cache yet. This method will usually mark unknown entries as cold and
known entries as hot.
Parameters:
key - the key (may not be null)
value - the value (may not be null)
memory - the memory used for the given entry
Returns:
the old value, or null if there was no resident entry
|
| V |
put(K key, V value)
Add an entry to the cache using a memory size of 1.
|
| V |
put(K key, V value)
Add an entry to the cache using a memory size of 1.
Parameters:
key - the key (may not be null)
value - the value (may not be null)
Returns:
the old value, or null if there was no resident entry
|
| V |
remove(Object key)
Remove an entry.
|
| V |
remove(Object key)
Remove an entry. Both resident and non-resident entries can be
removed.
Parameters:
key - the key (may not be null)
Returns:
the old value, or null if there was no resident entry
|
| void |
setMaxMemory(long maxMemory)
Set the maximum memory this cache should use.
|
| void |
setMaxMemory(long maxMemory)
Set the maximum memory this cache should use. This will not
immediately cause entries to get removed however; it will only change
the limit. To resize the internal array, call the clear method.
Parameters:
maxMemory - the maximum size (1 or larger)
|
| int |
size()
Get the number of resident entries.
|
| int |
size()
Get the number of resident entries.
Returns:
the number of entries
|
| int |
sizeHot()
Get the number of hot entries in the cache.
|
| int |
sizeHot()
Get the number of hot entries in the cache.
Returns:
the number of hot entries
|
| int |
sizeMapArray()
Get the length of the internal map array.
|
| int |
sizeMapArray()
Get the length of the internal map array.
Returns:
the size of the array
|
| int |
sizeNonResident()
Get the number of non-resident entries in the cache.
|
| int |
sizeNonResident()
Get the number of non-resident entries in the cache.
Returns:
the number of non-resident entries
|
| int |
sizeOf(K key, V value)
Get the size of the given value.
|
| int |
sizeOf(K key, V value)
Get the size of the given value. The default implementation returns 1.
Parameters:
key - the key
value - the value
Returns:
the size
|