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 LIRS replacement algorithm invented by Xiaodong Zhang and Song Jiang as described in https://web.cse.ohio-state.edu/~zhang.574/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.
| Modifier and Type | Class and Description |
|---|---|
| public static class | CacheLongKeyLIRS.
The cache configuration. |
| pack-priv static class | |
| private static class |
| Modifier and Type | Field and Description |
|---|---|
| private long | maxMemory
The maximum memory this cache should use. |
| private final int | |
| private final int | |
| private final int | |
| private final int | |
| private final CacheLongKeyLIRS. | |
| private final int | |
| private final int |
| Access | Constructor and Description |
|---|---|
| public | CacheLongKeyLIRS(CacheLongKeyLIRS.
the configuration configCreate a new cache with the given memory size. |
| Modifier and Type | Method and Description |
|---|---|
| public void | |
| public boolean | Returns: true if there is a resident entrythe key (may not be null) key)Check whether there is a resident entry for the given key. |
| public boolean | Returns: true if it is storedthe value value)Check whether the given value is stored. |
| public synchronized Set | |
| private CacheLongKeyLIRS. | |
| public V | Returns: the value, or null if there is no resident entrythe key (may not be null) key)Get the value for the given key if the entry is cached. |
| pack-priv static int | |
| public long | |
| public Map | |
| public long | Returns: data items size limitDetermines max size of the data item size to fit into cache |
| public long | |
| public long | Returns: the memory, or 0 if there is no resident entrythe key (may not be null) key)Get the memory used for the given key. |
| public static int | |
| public long | |
| private CacheLongKeyLIRS. | |
| private int | |
| public long | |
| public boolean | |
| public List | Returns: the key listif true, only keys for the cold entries are returned cold, boolean true for non-resident entries nonResident)Get the list of keys. |
| public Set | |
| public V | Returns: the value, or null if there is no resident entrythe key (may not be null) key)Get the value for the given key if the entry is cached. |
| public V | Returns: the old value, or null if there was no resident entrythe key (may not be null) key, V the value (may not be null) value)Add an entry to the cache using the average memory size. |
| public V | Returns: the old value, or null if there was no resident entrythe key (may not be null) key, V the value (may not be null) value, long the memory used for the given entry memory)Add an entry to the cache. |
| public void | |
| public V | Returns: the old value, or null if there was no resident entrythe key (may not be null) key)Remove an entry. |
| private CacheLongKeyLIRS. | |
| public void | setMaxMemory(long
the maximum size (1 or larger) in bytes maxMemory)Set the maximum memory this cache should use. |
| public int | |
| public int | |
| public int | |
| public int | Returns: the number of non-resident entriesGet the number of non-resident entries in the cache. |
| protected long | |
| public void | |
| public List |
| maxMemory | back to summary |
|---|---|
| private long maxMemory The maximum memory this cache should use. | |
| nonResidentQueueSize | back to summary |
|---|---|
| private final int nonResidentQueueSize | |
| nonResidentQueueSizeHigh | back to summary |
|---|---|
| private final int nonResidentQueueSizeHigh | |
| segmentCount | back to summary |
|---|---|
| private final int segmentCount | |
| segmentMask | back to summary |
|---|---|
| private final int segmentMask | |
| segments | back to summary |
|---|---|
| private final CacheLongKeyLIRS. | |
| segmentShift | back to summary |
|---|---|
| private final int segmentShift | |
| stackMoveDistance | back to summary |
|---|---|
| private final int stackMoveDistance | |
| CacheLongKeyLIRS | back to summary |
|---|---|
| public CacheLongKeyLIRS(CacheLongKeyLIRS. Create a new cache with the given memory size.
| |
| clear | back to summary |
|---|---|
| public void clear() Remove all entries. | |
| containsKey | back to summary |
|---|---|
| public boolean containsKey(long key) Check whether there is a resident entry for the given key. This method does not adjust the internal state of the cache.
| |
| containsValue | back to summary |
|---|---|
| public boolean containsValue(V value) Check whether the given value is stored.
| |
| entrySet | back to summary |
|---|---|
| public synchronized Set Get the entry set for all resident entries. | |
| find | back to summary |
|---|---|
| private CacheLongKeyLIRS. | |
| get | back to summary |
|---|---|
| public V get(long 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.
| |
| getHash | back to summary |
|---|---|
| pack-priv static int getHash(long key) Get the hash code for the given key. The hash code is further enhanced to spread the values more evenly.
| |
| getHits | back to summary |
|---|---|
| public long getHits() Get the number of cache hits.
| |
| getMap | back to summary |
|---|---|
| public Map Convert this cache to a map. | |
| getMaxItemSize | back to summary |
|---|---|
| public long getMaxItemSize() Determines max size of the data item size to fit into cache
| |
| getMaxMemory | back to summary |
|---|---|
| public long getMaxMemory() Get the maximum memory to use.
| |
| getMemory | back to summary |
|---|---|
| public long getMemory(long key) Get the memory used for the given key.
| |
| getMemoryOverhead | back to summary |
|---|---|
| public static int getMemoryOverhead() Get the memory overhead per value.
| |
| getMisses | back to summary |
|---|---|
| public long getMisses() Get the number of cache misses.
| |
| getSegment | back to summary |
|---|---|
| private CacheLongKeyLIRS. | |
| getSegmentIndex | back to summary |
|---|---|
| private int getSegmentIndex(int hash) | |
| getUsedMemory | back to summary |
|---|---|
| public long getUsedMemory() Get the currently used memory.
| |
| isEmpty | back to summary |
|---|---|
| public boolean isEmpty() Check whether the cache is empty.
| |
| keys | back to summary |
|---|---|
| public List Get the list of keys. This method allows to read the internal state of the cache. | |
| keySet | back to summary |
|---|---|
| public Set Get the set of keys for resident entries. | |
| peek | back to summary |
|---|---|
| public V peek(long key) Get the value for the given key if the entry is cached. This method does not modify the internal state.
| |
| put | back to summary |
|---|---|
| public V put(long key, V value) Add an entry to the cache using the average memory size.
| |
| put | back to summary |
|---|---|
| public V put(long key, V value, long 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.
| |
| putAll | back to summary |
|---|---|
| public void putAll(Map<Long, ? extends V> m) Add all elements of the map to this cache. | |
| remove | back to summary |
|---|---|
| public V remove(long key) Remove an entry. Both resident and non-resident entries can be removed.
| |
| resizeIfNeeded | back to summary |
|---|---|
| private CacheLongKeyLIRS. | |
| setMaxMemory | back to summary |
|---|---|
| public 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.
| |
| size | back to summary |
|---|---|
| public int size() Get the number of resident entries.
| |
| sizeHot | back to summary |
|---|---|
| public int sizeHot() Get the number of hot entries in the cache.
| |
| sizeMapArray | back to summary |
|---|---|
| public int sizeMapArray() Get the length of the internal map array.
| |
| sizeNonResident | back to summary |
|---|---|
| public int sizeNonResident() Get the number of non-resident entries in the cache.
| |
| sizeOf | back to summary |
|---|---|
| protected long sizeOf(V value) Get the size of the given value. The default implementation returns 16.
| |
| trimNonResidentQueue | back to summary |
|---|---|
| public void trimNonResidentQueue() Loop through segments, trimming the non resident queue. | |
| values | back to summary |
|---|---|
| public List Get the values for all resident entries.
| |
| Modifier and Type | Field and Description |
|---|---|
| public long | maxMemory
The maximum memory to use (1 or larger). |
| public final int | nonResidentQueueSize
Low water mark for the number of entries in the non-resident queue, as a factor of the number of all other entries in the map. |
| public final int | nonResidentQueueSizeHigh
High watermark for the number of entries in the non-resident queue, as a factor of the number of all other entries in the map |
| public int | segmentCount
The number of cache segments (must be a power of 2). |
| public int | stackMoveDistance
How many other item are to be moved to the top of the stack before the current item is moved. |
| Access | Constructor and Description |
|---|---|
| public |
| maxMemory | back to summary |
|---|---|
| public long maxMemory The maximum memory to use (1 or larger). | |
| nonResidentQueueSize | back to summary |
|---|---|
| public final int nonResidentQueueSize Low water mark for the number of entries in the non-resident queue, as a factor of the number of all other entries in the map. | |
| nonResidentQueueSizeHigh | back to summary |
|---|---|
| public final int nonResidentQueueSizeHigh High watermark for the number of entries in the non-resident queue, as a factor of the number of all other entries in the map | |
| segmentCount | back to summary |
|---|---|
| public int segmentCount The number of cache segments (must be a power of 2). | |
| stackMoveDistance | back to summary |
|---|---|
| public int stackMoveDistance How many other item are to be moved to the top of the stack before the current item is moved. | |
| Config | back to summary |
|---|---|
| public Config() | |
| Modifier and Type | Field and Description |
|---|---|
| pack-priv final long | key
The key. |
| pack-priv CacheLongKeyLIRS. | mapNext
The next entry in the map (the chained entry). |
| pack-priv final long | memory
The estimated memory used. |
| pack-priv CacheLongKeyLIRS. | queueNext
The next entry in the queue (either the resident queue or the non-resident queue). |
| pack-priv CacheLongKeyLIRS. | queuePrev
The previous entry in the queue. |
| pack-priv WeakReference | reference
Weak reference to the value. |
| pack-priv CacheLongKeyLIRS. | stackNext
The next entry in the stack. |
| pack-priv CacheLongKeyLIRS. | stackPrev
The previous entry in the stack. |
| pack-priv int | topMove
When the item was last moved to the top of the stack. |
| pack-priv static final int | |
| pack-priv V | value
The value. |
| Access | Constructor and Description |
|---|---|
| pack-priv | |
| pack-priv | |
| pack-priv |
| Modifier and Type | Method and Description |
|---|---|
| pack-priv long | |
| pack-priv V | |
| pack-priv boolean |
| key | back to summary |
|---|---|
| pack-priv final long key The key. | |
| mapNext | back to summary |
|---|---|
| pack-priv CacheLongKeyLIRS. The next entry in the map (the chained entry). | |
| memory | back to summary |
|---|---|
| pack-priv final long memory The estimated memory used. | |
| queueNext | back to summary |
|---|---|
| pack-priv CacheLongKeyLIRS. The next entry in the queue (either the resident queue or the non-resident queue). | |
| queuePrev | back to summary |
|---|---|
| pack-priv CacheLongKeyLIRS. The previous entry in the queue. | |
| reference | back to summary |
|---|---|
| pack-priv WeakReference<V> reference Weak reference to the value. Set to null for resident entries. | |
| stackNext | back to summary |
|---|---|
| pack-priv CacheLongKeyLIRS. The next entry in the stack. | |
| stackPrev | back to summary |
|---|---|
| pack-priv CacheLongKeyLIRS. The previous entry in the stack. | |
| topMove | back to summary |
|---|---|
| pack-priv int topMove When the item was last moved to the top of the stack. | |
| TOTAL_MEMORY_OVERHEAD | back to summary |
|---|---|
| pack-priv static final int TOTAL_MEMORY_OVERHEAD | |
| value | back to summary |
|---|---|
| pack-priv V value The value. Set to null for non-resident-cold entries. | |
| Entry | back to summary |
|---|---|
| pack-priv Entry() | |
| Entry | back to summary |
|---|---|
| pack-priv Entry(long key, V value, long memory) | |
| Entry | back to summary |
|---|---|
| pack-priv Entry(CacheLongKeyLIRS. | |
| getMemory | back to summary |
|---|---|
| pack-priv long getMemory() | |
| getValue | back to summary |
|---|---|
| pack-priv V getValue() | |
| isHot | back to summary |
|---|---|
| pack-priv boolean isHot() Whether this entry is hot. Cold entries are in one of the two queues.
| |
| Modifier and Type | Field and Description |
|---|---|
| pack-priv final CacheLongKeyLIRS. | entries
The map array. |
| pack-priv long | hits
The number of cache hits. |
| pack-priv int | mapSize
The number of (hot, cold, and non-resident) entries in the map. |
| private final int | mask
The bit mask that is applied to the key hash code to get the index in the map array. |
| private long | maxMemory
The maximum memory this cache should use in bytes. |
| pack-priv long | misses
The number of cache misses. |
| private final int | nonResidentQueueSize
Low watermark for the number of entries in the non-resident queue, as a factor of the number of entries in the map. |
| private final int | nonResidentQueueSizeHigh
High watermark for the number of entries in the non-resident queue, as a factor of the number of entries in the map. |
| private final CacheLongKeyLIRS. | queue
The queue of resident cold entries. |
| private final CacheLongKeyLIRS. | queue2
The queue of non-resident cold entries. |
| pack-priv int | queue2Size
The size of the LIRS queue for non-resident cold entries. |
| pack-priv int | queueSize
The size of the LIRS queue for resident cold entries. |
| private final CacheLongKeyLIRS. | stack
The stack of recently referenced elements. |
| private int | stackMoveCounter
The number of times any item was moved to the top of the stack. |
| private final int | stackMoveDistance
How many other item are to be moved to the top of the stack before the current item is moved. |
| private int | stackSize
The number of entries in the stack. |
| pack-priv long | usedMemory
The currently used memory. |
| Access | Constructor and Description |
|---|---|
| pack-priv | Segment(long
the maximum memory to use maxMemory, int the number of other entries to be moved to
the top of the stack before moving an entry to the top stackMoveDistance, int the number of hash table buckets (must be a power of 2) len, int the non-resident queue size low watermark factor nonResidentQueueSize, int the non-resident queue size high watermark factor nonResidentQueueSizeHigh)Create a new cache segment. |
| pack-priv | Segment(CacheLongKeyLIRS.
the old segment old,the number of hash table buckets (must be a power of 2) len)Create a new cache segment from an existing one. |
| Modifier and Type | Method and Description |
|---|---|
| private void | access(CacheLongKeyLIRS.
entry to record access for eAccess an item, moving the entry to the top of the stack or front of the queue if found. |
| private void | |
| private void | |
| private void | |
| private void | |
| private void | |
| private void | |
| private void | |
| pack-priv CacheLongKeyLIRS. | Returns: the entry (might be a non-resident)the key key, int the hash hash)Try to find an entry in the map. |
| pack-priv synchronized V | Returns: the value, or null if there is no resident entrythe entry eGet the value from the given entry. |
| pack-priv int | Returns: 0 if no resizing is needed, or the new lengthCalculate the new number of hash table buckets if the internal map should be re-sized. |
| pack-priv synchronized List | Returns: the key listif true, only keys for the cold entries are returned cold, boolean true for non-resident entries nonResident)Get the list of keys. |
| pack-priv synchronized Set | |
| private void | |
| pack-priv synchronized V | Returns: the old value, or null if there was no resident entrythe key (may not be null) key, int the hash hash, V the value (may not be null) value, long the memory used for the given entry memory)Add an entry to the cache. |
| pack-priv synchronized V | Returns: the old value, or null if there was no resident entrythe key (may not be null) key, int the hash hash)Remove an entry. |
| private void | |
| private void | |
| pack-priv void | setMaxMemory(long
the maximum size (1 or larger) in bytes maxMemory)Set the maximum memory this cache should use. |
| pack-priv void |
| entries | back to summary |
|---|---|
| pack-priv final CacheLongKeyLIRS. The map array. The size is always a power of 2. | |
| hits | back to summary |
|---|---|
| pack-priv long hits The number of cache hits. | |
| mapSize | back to summary |
|---|---|
| pack-priv int mapSize The number of (hot, cold, and non-resident) entries in the map. | |
| mask | back to summary |
|---|---|
| private final int mask The bit mask that is applied to the key hash code to get the index in the map array. The mask is the length of the array minus one. | |
| maxMemory | back to summary |
|---|---|
| private long maxMemory The maximum memory this cache should use in bytes. | |
| misses | back to summary |
|---|---|
| pack-priv long misses The number of cache misses. | |
| nonResidentQueueSize | back to summary |
|---|---|
| private final int nonResidentQueueSize Low watermark for the number of entries in the non-resident queue, as a factor of the number of entries in the map. | |
| nonResidentQueueSizeHigh | back to summary |
|---|---|
| private final int nonResidentQueueSizeHigh High watermark for the number of entries in the non-resident queue, as a factor of the number of entries in the map. | |
| queue | back to summary |
|---|---|
| private final CacheLongKeyLIRS. The queue of resident cold entries. There is always at least one entry: the head entry. | |
| queue2 | back to summary |
|---|---|
| private final CacheLongKeyLIRS. The queue of non-resident cold entries. There is always at least one entry: the head entry. | |
| queue2Size | back to summary |
|---|---|
| pack-priv int queue2Size The size of the LIRS queue for non-resident cold entries. | |
| queueSize | back to summary |
|---|---|
| pack-priv int queueSize The size of the LIRS queue for resident cold entries. | |
| stack | back to summary |
|---|---|
| private final CacheLongKeyLIRS. The stack of recently referenced elements. This includes all hot entries, and the recently referenced cold entries. Resident cold entries that were not recently referenced, as well as non-resident cold entries, are not in the stack. There is always at least one entry: the head entry. | |
| stackMoveCounter | back to summary |
|---|---|
| private int stackMoveCounter The number of times any item was moved to the top of the stack. | |
| stackMoveDistance | back to summary |
|---|---|
| private final int stackMoveDistance How many other item are to be moved to the top of the stack before the current item is moved. | |
| stackSize | back to summary |
|---|---|
| private int stackSize The number of entries in the stack. | |
| usedMemory | back to summary |
|---|---|
| pack-priv long usedMemory The currently used memory. | |
| Segment | back to summary |
|---|---|
| pack-priv Segment(long maxMemory, int stackMoveDistance, int len, int nonResidentQueueSize, int nonResidentQueueSizeHigh) Create a new cache segment.
| |
| Segment | back to summary |
|---|---|
| pack-priv Segment(CacheLongKeyLIRS. Create a new cache segment from an existing one. The caller must synchronize on the old segment, to avoid concurrent modifications.
| |
| access | back to summary |
|---|---|
| private void access(CacheLongKeyLIRS. Access an item, moving the entry to the top of the stack or front of the queue if found.
| |
| addToMap | back to summary |
|---|---|
| private void addToMap(CacheLongKeyLIRS. | |
| addToQueue | back to summary |
|---|---|
| private void addToQueue(CacheLongKeyLIRS. | |
| addToStack | back to summary |
|---|---|
| private void addToStack(CacheLongKeyLIRS. | |
| addToStackBottom | back to summary |
|---|---|
| private void addToStackBottom(CacheLongKeyLIRS. | |
| convertOldestHotToCold | back to summary |
|---|---|
| private void convertOldestHotToCold() | |
| evict | back to summary |
|---|---|
| private void evict() Evict cold entries (resident and non-resident) until the memory limit is reached. The new entry is added as a cold entry, except if it is the only entry. | |
| evictBlock | back to summary |
|---|---|
| private void evictBlock() | |
| find | back to summary |
|---|---|
| pack-priv CacheLongKeyLIRS. Try to find an entry in the map.
| |
| get | back to summary |
|---|---|
| pack-priv synchronized V get(CacheLongKeyLIRS. Get the value from the given entry. This method adjusts the internal state of the cache sometimes, to ensure commonly used entries stay in the cache.
| |
| getNewMapLen | back to summary |
|---|---|
| pack-priv int getNewMapLen() Calculate the new number of hash table buckets if the internal map should be re-sized.
| |
| keys | back to summary |
|---|---|
| pack-priv synchronized List Get the list of keys. This method allows to read the internal state of the cache. | |
| keySet | back to summary |
|---|---|
| pack-priv synchronized Set Get the set of keys for resident entries. | |
| pruneStack | back to summary |
|---|---|
| private void pruneStack() Ensure the last entry of the stack is cold. | |
| put | back to summary |
|---|---|
| pack-priv synchronized V put(long key, int hash, V value, long 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.
| |
| remove | back to summary |
|---|---|
| pack-priv synchronized V remove(long key, int hash) Remove an entry. Both resident and non-resident entries can be removed.
| |
| removeFromQueue | back to summary |
|---|---|
| private void removeFromQueue(CacheLongKeyLIRS. | |
| removeFromStack | back to summary |
|---|---|
| private void removeFromStack(CacheLongKeyLIRS. Remove the entry from the stack. The head itself must not be removed.
| |
| setMaxMemory | back to summary |
|---|---|
| pack-priv 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.
| |
| trimNonResidentQueue | back to summary |
|---|---|
| pack-priv void trimNonResidentQueue() | |