protected void shrink()

in commons-jcs3-core/src/main/java/org/apache/commons/jcs3/engine/memory/shrinking/ShrinkerThread.java [105:197]


    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;
        }
    }