public class LRUMap<K,V> extends AbstractLinkedMap<K,V> implements BoundedMap<K,V>, Serializable, Cloneable
Map
implementation with a fixed maximum size which removes
the least recently used entry if an entry is added when full.
The least recently used algorithm works on the get and put operations only. Iteration of any kind, including setting the value by iteration, does not change the order. Queries such as containsKey and containsValue or access via views also do not change the order.
A somewhat subtle ramification of the least recently used
algorithm is that calls to get(Object)
stand a very good chance
of modifying the map's iteration order and thus invalidating any
iterators currently in use. It is therefore suggested that iterations
over an LRUMap
instance access entry values only through a
MapIterator
or AbstractHashedMap.entrySet()
iterator.
The map implements OrderedMap
and entries may be queried using
the bidirectional OrderedMapIterator
. The order returned is
least recently used to most recently used. Iterators from map views can
also be cast to OrderedIterator
if required.
All the available iterators can be reset back to the start by casting to
ResettableIterator
and calling reset()
.
Note that LRUMap is not synchronized and is not thread-safe.
If you wish to use this map from multiple threads concurrently, you must use
appropriate synchronization. The simplest approach is to wrap this map
using Collections.synchronizedMap(Map)
. This class may throw
NullPointerException
's when accessed by concurrent threads.
AbstractLinkedMap.EntrySetIterator<K,V>, AbstractLinkedMap.KeySetIterator<K>, AbstractLinkedMap.LinkEntry<K,V>, AbstractLinkedMap.LinkIterator<K,V>, AbstractLinkedMap.LinkMapIterator<K,V>, AbstractLinkedMap.ValuesIterator<V>
AbstractHashedMap.EntrySet<K,V>, AbstractHashedMap.HashEntry<K,V>, AbstractHashedMap.HashIterator<K,V>, AbstractHashedMap.HashMapIterator<K,V>, AbstractHashedMap.KeySet<K>, AbstractHashedMap.Values<V>
AbstractMap.SimpleEntry<K,V>, AbstractMap.SimpleImmutableEntry<K,V>
Modifier and Type | Field and Description |
---|---|
protected static int |
DEFAULT_MAX_SIZE
Default maximum size
|
DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_THRESHOLD, GETKEY_INVALID, GETVALUE_INVALID, MAXIMUM_CAPACITY, NO_NEXT_ENTRY, NO_PREVIOUS_ENTRY, NULL, REMOVE_INVALID, SETVALUE_INVALID
Constructor and Description |
---|
LRUMap()
Constructs a new empty map with a maximum size of 100.
|
LRUMap(int maxSize)
Constructs a new, empty map with the specified maximum size.
|
LRUMap(int maxSize,
boolean scanUntilRemovable)
Constructs a new, empty map with the specified maximum size.
|
LRUMap(int maxSize,
float loadFactor)
Constructs a new, empty map with the specified initial capacity and
load factor.
|
LRUMap(int maxSize,
float loadFactor,
boolean scanUntilRemovable)
Constructs a new, empty map with the specified initial capacity and
load factor.
|
LRUMap(Map<? extends K,? extends V> map)
Constructor copying elements from another map.
|
LRUMap(Map<? extends K,? extends V> map,
boolean scanUntilRemovable)
Constructor copying elements from another map.
|
Modifier and Type | Method and Description |
---|---|
protected void |
addMapping(int hashIndex,
int hashCode,
K key,
V value)
Adds a new key-value mapping into this map.
|
LRUMap<K,V> |
clone()
Clones the map without cloning the keys or values.
|
protected void |
doReadObject(ObjectInputStream in)
Reads the data necessary for
put() to work in the superclass. |
protected void |
doWriteObject(ObjectOutputStream out)
Writes the data necessary for
put() to work in deserialization. |
V |
get(Object key)
Gets the value mapped to the key specified.
|
boolean |
isFull()
Returns true if this map is full and no new mappings can be added.
|
boolean |
isScanUntilRemovable()
Whether this LRUMap will scan until a removable entry is found when the
map is full.
|
int |
maxSize()
Gets the maximum size of the map (the bound).
|
protected void |
moveToMRU(AbstractLinkedMap.LinkEntry<K,V> entry)
Moves an entry to the MRU position at the end of the list.
|
protected boolean |
removeLRU(AbstractLinkedMap.LinkEntry<K,V> entry)
Subclass method to control removal of the least recently used entry from the map.
|
protected void |
reuseMapping(AbstractLinkedMap.LinkEntry<K,V> entry,
int hashIndex,
int hashCode,
K key,
V value)
Reuses an entry by removing it and moving it to a new place in the map.
|
protected void |
updateEntry(AbstractHashedMap.HashEntry<K,V> entry,
V newValue)
Updates an existing key-value mapping.
|
addEntry, clear, containsValue, createEntry, createEntrySetIterator, createKeySetIterator, createValuesIterator, entryAfter, entryBefore, firstKey, getEntry, getEntry, init, lastKey, mapIterator, nextKey, previousKey, removeEntry
calculateNewCapacity, calculateThreshold, checkCapacity, containsKey, convertKey, destroyEntry, ensureCapacity, entryHashCode, entryKey, entryNext, entrySet, entryValue, equals, hash, hashCode, hashIndex, isEmpty, isEqualKey, isEqualValue, keySet, put, putAll, remove, removeMapping, reuseEntry, size, toString, values
finalize, getClass, notify, notifyAll, wait, wait, wait
clear, containsKey, containsValue, entrySet, equals, hashCode, isEmpty, keySet, put, putAll, remove, size, values
mapIterator
containsKey, containsValue, entrySet, isEmpty, keySet, remove, size, values
protected static final int DEFAULT_MAX_SIZE
public LRUMap()
public LRUMap(int maxSize)
maxSize
- the maximum size of the mapIllegalArgumentException
- if the maximum size is less than onepublic LRUMap(int maxSize, boolean scanUntilRemovable)
maxSize
- the maximum size of the mapscanUntilRemovable
- scan until a removeable entry is found, default falseIllegalArgumentException
- if the maximum size is less than onepublic LRUMap(int maxSize, float loadFactor)
maxSize
- the maximum size of the maploadFactor
- the load factorIllegalArgumentException
- if the maximum size is less than oneIllegalArgumentException
- if the load factor is less than zeropublic LRUMap(int maxSize, float loadFactor, boolean scanUntilRemovable)
maxSize
- the maximum size of the maloadFactor
- the load factorscanUntilRemovable
- scan until a removeable entry is found, default falseIllegalArgumentException
- if the maximum size is less than oneIllegalArgumentException
- if the load factor is less than zeropublic LRUMap(Map<? extends K,? extends V> map)
The maximum size is set from the map's size.
map
- the map to copyNullPointerException
- if the map is nullIllegalArgumentException
- if the map is emptypublic LRUMap(Map<? extends K,? extends V> map, boolean scanUntilRemovable)
map
- the map to copyscanUntilRemovable
- scan until a removeable entry is found, default falseNullPointerException
- if the map is nullIllegalArgumentException
- if the map is emptypublic V get(Object key)
This operation changes the position of the key in the map to the most recently used position (first).
protected void moveToMRU(AbstractLinkedMap.LinkEntry<K,V> entry)
This implementation moves the updated entry to the end of the list.
entry
- the entry to updateprotected void updateEntry(AbstractHashedMap.HashEntry<K,V> entry, V newValue)
This implementation moves the updated entry to the top of the list
using moveToMRU(AbstractLinkedMap.LinkEntry)
.
updateEntry
in class AbstractHashedMap<K,V>
entry
- the entry to updatenewValue
- the new value to storeprotected void addMapping(int hashIndex, int hashCode, K key, V value)
This implementation checks the LRU size and determines whether to
discard an entry or not using removeLRU(AbstractLinkedMap.LinkEntry)
.
From Commons Collections 3.1 this method uses isFull()
rather
than accessing size
and maxSize
directly.
It also handles the scanUntilRemovable functionality.
addMapping
in class AbstractHashedMap<K,V>
hashIndex
- the index into the data array to store athashCode
- the hash code of the key to addkey
- the key to addvalue
- the value to addprotected void reuseMapping(AbstractLinkedMap.LinkEntry<K,V> entry, int hashIndex, int hashCode, K key, V value)
This method uses AbstractLinkedMap.removeEntry(org.apache.commons.collections4.map.AbstractHashedMap.HashEntry<K, V>, int, org.apache.commons.collections4.map.AbstractHashedMap.HashEntry<K, V>)
, AbstractHashedMap.reuseEntry(org.apache.commons.collections4.map.AbstractHashedMap.HashEntry<K, V>, int, int, K, V)
and AbstractLinkedMap.addEntry(org.apache.commons.collections4.map.AbstractHashedMap.HashEntry<K, V>, int)
.
entry
- the entry to reusehashIndex
- the index into the data array to store athashCode
- the hash code of the key to addkey
- the key to addvalue
- the value to addprotected boolean removeLRU(AbstractLinkedMap.LinkEntry<K,V> entry)
This method exists for subclasses to override. A subclass may wish to provide cleanup of resources when an entry is removed. For example:
protected boolean removeLRU(LinkEntry entry) { releaseResources(entry.getValue()); // release resources held by entry return true; // actually delete entry }
Alternatively, a subclass may choose to not remove the entry or selectively keep certain LRU entries. For example:
protected boolean removeLRU(LinkEntry entry) { if (entry.getKey().toString().startsWith("System.")) { return false; // entry not removed from LRUMap } else { return true; // actually delete entry } }The effect of returning false is dependent on the scanUntilRemovable flag. If the flag is true, the next LRU entry will be passed to this method and so on until one returns false and is removed, or every entry in the map has been passed. If the scanUntilRemovable flag is false, the map will exceed the maximum size.
NOTE: Commons Collections 3.0 passed the wrong entry to this method. This is fixed in version 3.1 onwards.
entry
- the entry to be removedtrue
public boolean isFull()
isFull
in interface BoundedMap<K,V>
true
if the map is fullpublic int maxSize()
maxSize
in interface BoundedMap<K,V>
public boolean isScanUntilRemovable()
public LRUMap<K,V> clone()
clone
in class AbstractHashedMap<K,V>
protected void doWriteObject(ObjectOutputStream out) throws IOException
put()
to work in deserialization.doWriteObject
in class AbstractHashedMap<K,V>
out
- the output streamIOException
- if an error occurs while writing to the streamprotected void doReadObject(ObjectInputStream in) throws IOException, ClassNotFoundException
put()
to work in the superclass.doReadObject
in class AbstractHashedMap<K,V>
in
- the input streamIOException
- if an error occurs while reading from the streamClassNotFoundException
- if an object read from the stream can not be loadedCopyright © 2001–2013 The Apache Software Foundation. All rights reserved.