in commons-jcs3-core/src/main/java/org/apache/commons/jcs3/engine/memory/shrinking/ShrinkerThread.java [106:198]
protected void shrink()
{
log.debug( "Shrinking memory cache for: {0}", this.cache::getCacheName);
final IMemoryCache<K, V> memCache = cache.getMemoryCache();
try
{
final Set<K> keys = memCache.getKeySet();
final int size = keys.size();
log.debug( "Keys size: {0}", size );
int spoolCount = 0;
for (final K key : keys)
{
final ICacheElement<K, V> cacheElement = memCache.getQuiet( key );
if ( cacheElement == null )
{
continue;
}
final IElementAttributes attributes = cacheElement.getElementAttributes();
boolean remove = false;
final long now = System.currentTimeMillis();
// If the element is not eternal, check if it should be
// removed and remove it if so.
if ( !attributes.getIsEternal() )
{
remove = cache.isExpired( cacheElement, now,
ElementEventType.EXCEEDED_MAXLIFE_BACKGROUND,
ElementEventType.EXCEEDED_IDLETIME_BACKGROUND );
if ( remove )
{
memCache.remove( key );
}
}
// If the item is not removed, check is it has been idle
// long enough to be spooled.
if ( !remove && maxMemoryIdleTime != -1 )
{
if ( !spoolLimit || spoolCount < this.maxSpoolPerRun )
{
final long lastAccessTime = attributes.getLastAccessTime();
if ( lastAccessTime + maxMemoryIdleTime < now )
{
log.debug( "Exceeded memory idle time: {0}", key );
// Shouldn't we ensure that the element is
// spooled before removing it from memory?
// No the disk caches have a purgatory. If it fails
// to spool that does not affect the
// responsibilities of the memory cache.
spoolCount++;
memCache.remove( key );
memCache.waterfal( cacheElement );
}
}
else
{
log.debug( "spoolCount = \"{0}\"; maxSpoolPerRun = \"{1}\"",
spoolCount, maxSpoolPerRun );
// stop processing if limit has been reached.
if ( spoolLimit && spoolCount >= this.maxSpoolPerRun )
{
return;
}
}
}
}
}
catch ( final Throwable t )
{
log.info( "Unexpected trouble in shrink cycle", t );
// concurrent modifications should no longer be a problem
// It is up to the IMemoryCache to return an array of keys
// stop for now
return;
}
}