/*
 * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (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.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.search;

import com.arsdigita.util.Assert;
import com.arsdigita.util.Cache;

import org.apache.log4j.Logger;

/**
 * Implements a timed-expiry result set cache.
 */
public class TimedResultCache implements ResultCache {
    
    private static final Logger s_log = Logger.getLogger(TimedResultCache.class);

    private Cache m_cache;    
    
    private int m_count;

    /**
     * Create a new result cache with room for
     * 'size' entries, valid for a specified
     * maximum age.
     * @param count number of documents per result set to cache
     * @param size max entries to cache
     * @param maxAge maximum age in milliseconds
     */
    public TimedResultCache(int count,
                            long size,
                            long maxAge) {
        m_cache = new Cache(size, maxAge);
        m_count = count;
    }

    /**
     * Stores a result set in the cache
     * @param query the query to store results for
     * @param results the results to cache
     */
    public void put(QuerySpecification query,
                    ResultSet results) {
        Assert.exists(query, QuerySpecification.class);
        Assert.exists(results, ResultSet.class);

        CachedResultSet wrapper = new CachedResultSet(query,
                                                      results,
                                                      m_count);

        if (s_log.isDebugEnabled()) {
            s_log.debug("Storing result for " + query + 
                        " count " + wrapper.getCount() +
                        " time " + wrapper.getQueryTime() + 
                        " engine " + wrapper.getEngine());
        }

        m_cache.put(query, wrapper);
    }
    
    /**
     * Retrieves a result set from the cache
     * @param query the query to get results for
     * @return the cached result set, or null
     */
    public ResultSet get(QuerySpecification query) {
        Assert.exists(query, QuerySpecification.class);

        ResultSet results = (ResultSet)m_cache.get(query);
        
        if (s_log.isDebugEnabled()) {
            s_log.debug("Retrieved result for " + query + 
                        (results == null ? " none cached" : (
                        " count " + results.getCount() +
                        " time " + results.getQueryTime() + 
                        " engine " + results.getEngine())));
        }

        return results;
    }
}
