package org.apache.commons.jcs.auxiliary.disk.jdbc;

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArraySet;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.commons.jcs.log.Log;
import org.apache.commons.jcs.log.LogManager;
import org.apache.commons.jcs.utils.timing.ElapsedTimer;

/**
 * Calls delete expired on the disk caches. The shrinker is run by a clock daemon. The shrinker
 * calls delete on each region. It pauses between calls.
 * <p>
 * @author Aaron Smuts
 */
public class ShrinkerThread
    implements Runnable
{
    /** The logger. */
    private static final Log log = LogManager.getLog( ShrinkerThread.class );

    /** A set of JDBCDiskCache objects to call deleteExpired on. */
    private final CopyOnWriteArraySet<JDBCDiskCache<?, ?>> shrinkSet =
            new CopyOnWriteArraySet<>();

    /** Default time period to use. */
    private static final long DEFAULT_PAUSE_BETWEEN_REGION_CALLS_MILLIS = 5000;

    /**
     * How long should we wait between calls to deleteExpired when we are iterating through the list
     * of regions. Delete can lock the table. We want to give clients a chance to get some work
     * done.
     */
    private long pauseBetweenRegionCallsMillis = DEFAULT_PAUSE_BETWEEN_REGION_CALLS_MILLIS;

    /**
     * Does nothing special.
     */
    protected ShrinkerThread()
    {
        super();
    }

    /**
     * Adds a JDBC disk cache to the set of disk cache to shrink.
     * <p>
     * @param diskCache
     */
    public void addDiskCacheToShrinkList( JDBCDiskCache<?, ?> diskCache )
    {
        // the set will prevent dupes.
        // we could also just add these to a hashmap by region name
        // but that might cause a problem if you wanted to use two different
        // jbdc disk caches for the same region.
        shrinkSet.add( diskCache );
    }

    /**
     * Calls deleteExpired on each item in the set. It pauses between each call.
     */
    @Override
    public void run()
    {
        try
        {
            deleteExpiredFromAllRegisteredRegions();
        }
        catch ( Throwable e )
        {
            log.error( "Caught an exception while trying to delete expired items.", e );
        }
    }

    /**
     * Deletes the expired items from all the registered regions.
     */
    private void deleteExpiredFromAllRegisteredRegions()
    {
        log.info( "Running JDBC disk cache shrinker. Number of regions [{0}]",
                () -> shrinkSet.size() );

        for (Iterator<JDBCDiskCache<?, ?>> i = shrinkSet.iterator(); i.hasNext();)
        {
            JDBCDiskCache<?, ?> cache = i.next();
            ElapsedTimer timer = new ElapsedTimer();
            int deleted = cache.deleteExpired();

            log.info( "Deleted [{0}] expired for region [{1}] for table [{2}] in {3} ms.",
                    deleted, cache.getCacheName(), cache.getTableName(), timer.getElapsedTime() );

            // don't pause after the last call to delete expired.
            if ( i.hasNext() )
            {
                log.info( "Pausing for [{0}] ms before shrinking the next region.",
                        this.getPauseBetweenRegionCallsMillis() );

                try
                {
                    Thread.sleep( this.getPauseBetweenRegionCallsMillis() );
                }
                catch ( InterruptedException e )
                {
                    log.warn( "Interrupted while waiting to delete expired for the next region." );
                }
            }
        }
    }

    /**
     * How long should we wait between calls to deleteExpired when we are iterating through the list
     * of regions.
     * <p>
     * @param pauseBetweenRegionCallsMillis The pauseBetweenRegionCallsMillis to set.
     */
    public void setPauseBetweenRegionCallsMillis( long pauseBetweenRegionCallsMillis )
    {
        this.pauseBetweenRegionCallsMillis = pauseBetweenRegionCallsMillis;
    }

    /**
     * How long should we wait between calls to deleteExpired when we are iterating through the list
     * of regions.
     * <p>
     * @return Returns the pauseBetweenRegionCallsMillis.
     */
    public long getPauseBetweenRegionCallsMillis()
    {
        return pauseBetweenRegionCallsMillis;
    }
}
