To allow concurrent access from multiple threads, the methods in this class need to synchronize on a number of different objects:
CacheEntry
objects must be locked before they can be
usedArrayList
representing the circular
bufferHolder
objects in the clock
structure should be protected by synchronizing on the holderCacheEntry
's class
javadoc dictates the order when locking CacheEntry
objects. Additionally, we require that no thread should obtain any other
synchronization locks while it is holding a synchronization lock on the
clock structure or on a Holder
object. The threads are however
allowed to obtain synchronization locks on the clock structure or on a
holder while they are locking one or more CacheEntry
objects.
Modifier and Type | Class and Description |
---|---|
private class | ClockPolicy.Holder
Holder class which represents an entry in the cache. |
Modifier and Type | Field and Description |
---|---|
private final ConcurrentCache | cacheManager
The cache manager for which this replacement policy is used. |
private final ArrayList | clock
The circular clock buffer which holds all the entries in the cache. |
private final AtomicInteger | freeEntries
The number of free entries. |
private int | hand
The current position of the clock hand. |
private final AtomicBoolean | isShrinking
Tells whether there currently is a thread in the |
private static final float | MAX_ROTATION
How large part of the clock to look at before giving up in
|
private final int | maxSize
The maximum size of the cache. |
private static final int | MIN_ITEMS_TO_CHECK
The minimum number of items to check before we decide to give up looking for evictable entries when rotating the clock. |
private static final float | PART_OF_CLOCK_FOR_SHRINK
How large part of the clock to look at before giving up finding
an evictable entry in |
Access | Constructor and Description |
---|---|
pack-priv | ClockPolicy(ConcurrentCache
the cache manager that requests this policy cacheManager, int the initial capacity of the cache initialSize, int the maximum size of the cache maxSize)Create a new |
Modifier and Type | Method and Description |
---|---|
public void | doShrink()
Implements org. |
public void | insertEntry(CacheEntry
the entry to insert (must be locked) entry)Implements org. |
private boolean | Returns: whether or not this entry can be evicted (provided that itsCacheable is cleaned first)the entry to check e, ClockPolicy.the holder which holds the entry h,tells whether or not the recently used flag
should be cleared on the entry ( clearRecentlyUsedFlag)true only when called as part of
a normal clock rotation)Check if an entry can be evicted. |
private ClockPolicy. | Returns: the holder under the clock hand, ornull if the clock is
emptyGet the holder under the clock hand, and move the hand to the next holder. |
private void | removeHolder(int
position of the holder pos, ClockPolicy.the holder to remove hRemove the holder at the given clock position. |
private ClockPolicy. | Returns: a holder that we can reuse, ornull if we didn't
find onethe entry to insert entry, boolean tells whether evictions are allowed (normally
allowEvictions)true if the cache is full and false otherwise)Rotate the clock in order to find a free space for a new entry. |
private void | |
public int | size()
Implements org. |
cacheManager | back to summary |
---|---|
private final ConcurrentCache cacheManager The cache manager for which this replacement policy is used. |
clock | back to summary |
---|---|
private final ArrayList<ClockPolicy. The circular clock buffer which holds all the entries in the
cache. Accesses to |
freeEntries | back to summary |
---|---|
private final AtomicInteger freeEntries The number of free entries. This is the number of objects that have been removed from the cache and whose entries are free to be reused without eviction. |
hand | back to summary |
---|---|
private int hand The current position of the clock hand. |
isShrinking | back to summary |
---|---|
private final AtomicBoolean isShrinking Tells whether there currently is a thread in the |
MAX_ROTATION | back to summary |
---|---|
private static final float MAX_ROTATION How large part of the clock to look at before giving up in
|
maxSize | back to summary |
---|---|
private final int maxSize The maximum size of the cache. When this size is exceeded, entries must be evicted before new ones are inserted. |
MIN_ITEMS_TO_CHECK | back to summary |
---|---|
private static final int MIN_ITEMS_TO_CHECK The minimum number of items to check before we decide to give up looking for evictable entries when rotating the clock. |
PART_OF_CLOCK_FOR_SHRINK | back to summary |
---|---|
private static final float PART_OF_CLOCK_FOR_SHRINK How large part of the clock to look at before giving up finding
an evictable entry in |
ClockPolicy | back to summary |
---|---|
pack-priv ClockPolicy(ConcurrentCache cacheManager, int initialSize, int maxSize) Create a new
|
doShrink | back to summary |
---|---|
public void doShrink() Implements org. Try to shrink the clock if it's larger than its maximum size. |
insertEntry | back to summary |
---|---|
public void insertEntry(CacheEntry entry) throws StandardException Implements org. Insert an entry into the cache. If the maximum size is exceeded, evict a not recently used object from the cache. If there are no entries available for reuse, increase the size of the cache.
|
isEvictable | back to summary |
---|---|
private boolean isEvictable(CacheEntry e, ClockPolicy. Check if an entry can be evicted. Only entries that still are present in
the cache, are not kept and not recently used, can be evicted. This
method does not check whether the
|
moveHand | back to summary |
---|---|
private ClockPolicy. Get the holder under the clock hand, and move the hand to the next holder.
|
removeHolder | back to summary |
---|---|
private void removeHolder(int pos, ClockPolicy. Remove the holder at the given clock position.
|
rotateClock | back to summary |
---|---|
private ClockPolicy. Rotate the clock in order to find a free space for a new entry. If
|
shrinkMe | back to summary |
---|---|
private void shrinkMe() Perform the shrinking of the clock. This method should only be called by a single thread at a time. |
size | back to summary |
---|---|
public int size() Implements org. Doc from org. Get the number of entries allocated in the data structure that holds cached objects. This number could include empty entries for objects that have been removed from the cache, if those entries are still kept in the data structure for reuse.
|
recentlyUsed
required by the clock algorithm. The class
also implements the Callback
interface, so that
ConcurrentCache
can notify the clock policy about events
relevant to the clock algorithm.
Modifier and Type | Field and Description |
---|---|
private CacheEntry | entry
Reference to the |
private boolean | evicted
Flag which tells whether this holder has been evicted from the clock. |
private Cacheable | freedCacheable
Cacheable object from a removed object. |
pack-priv boolean | recentlyUsed
Flag indicating whether or not this entry has been accessed recently. |
Access | Constructor and Description |
---|---|
pack-priv |
Modifier and Type | Method and Description |
---|---|
public void | access()
Implements org. |
pack-priv synchronized boolean | Returns: true if the holder was successfully evicted,
false otherwiseEvict this holder from the clock if it is not associated with an entry. |
public synchronized void | free()
Implements org. |
pack-priv synchronized CacheEntry | Returns: the associated entryReturns the entry that is currently associated with this holder. |
pack-priv synchronized boolean | Returns: true if it has been evicted, false
otherwiseCheck whether this holder has been evicted from the clock. |
pack-priv synchronized void | |
pack-priv synchronized void | switchEntry(CacheEntry
the entry to associate this holder with e)Switch which entry the holder is associated with. |
pack-priv synchronized boolean | Returns: true if the holder has been associated with the
specified entry, false if someone else has taken it or
the holder has been evicted from the clockthe entry to associate the holder with (it must be locked
by the current thread) e)Associate this holder with the specified entry if the holder is free (that is, not associated with any other entry). |
entry | back to summary |
---|---|
private CacheEntry entry Reference to the |
evicted | back to summary |
---|---|
private boolean evicted Flag which tells whether this holder has been evicted from the clock. If it has been evicted, it can't be reused when a new entry is inserted. Only the owner of this holder's monitor is allowed to access this variable. |
freedCacheable | back to summary |
---|---|
private Cacheable freedCacheable Cacheable object from a removed object. If this object is non-null,
|
recentlyUsed | back to summary |
---|---|
pack-priv boolean recentlyUsed Flag indicating whether or not this entry has been accessed
recently. Should only be accessed/modified when the current thread
has locked the |
Holder | back to summary |
---|---|
pack-priv Holder(CacheEntry e) |
access | back to summary |
---|---|
public void access() Implements org. Mark this entry as recently used. Caller must have locked
|
evictIfFree | back to summary |
---|---|
pack-priv synchronized boolean evictIfFree() Evict this holder from the clock if it is not associated with an entry.
|
free | back to summary |
---|---|
public synchronized void free() Implements org. Mark this object as free and reusable. Caller must have locked
|
getEntry | back to summary |
---|---|
pack-priv synchronized CacheEntry getEntry() Returns the entry that is currently associated with this holder.
|
isEvicted | back to summary |
---|---|
pack-priv synchronized boolean isEvicted() Check whether this holder has been evicted from the clock.
|
setEvicted | back to summary |
---|---|
pack-priv synchronized void setEvicted() Mark this holder as evicted from the clock, effectively preventing reuse of the holder. Calling thread must have locked the holder's entry. |
switchEntry | back to summary |
---|---|
pack-priv synchronized void switchEntry(CacheEntry e) Switch which entry the holder is associated with. Will be called when we evict an entry to make room for a new one. When this method is called, the current thread must have locked both the entry that is evicted and the entry that is inserted.
|
takeIfFree | back to summary |
---|---|
pack-priv synchronized boolean takeIfFree(CacheEntry e) Associate this holder with the specified entry if the holder is free (that is, not associated with any other entry).
|