/*
 *  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. 
 *  
 */
package org.apache.directory.api.util;


import java.io.Externalizable;


/**
 * <p>
 * An implementation of a Map which has a maximum size and uses a Least Recently
 * Used algorithm to remove items from the Map when the maximum size is reached
 * and new items are added.
 * </p>
 * <p>
 * A synchronized version can be obtained with:
 * <code>Collections.synchronizedMap( theMapToSynchronize )</code> If it will
 * be accessed by multiple threads, you _must_ synchronize access to this Map.
 * Even concurrent get(Object) operations produce indeterminate behaviour.
 * </p>
 * <p>
 * Unlike the Collections 1.0 version, this version of LRUMap does use a true
 * LRU algorithm. The keys for all gets and puts are moved to the front of the
 * list. LRUMap is now a subclass of SequencedHashMap, and the "LRU" key is now
 * equivalent to LRUMap.getFirst().
 * </p>
 * 
 * @since Commons Collections 1.0
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public final class SynchronizedLRUMap extends SequencedHashMap implements Externalizable
{
    // add a serial version uid, so that if we change things in the future
    // without changing the format, we can still deserialize properly.
    private static final long serialVersionUID = 2197433140769957051L;

    private int maximumSize = 0;


    /**
     * Default constructor, primarily for the purpose of de-externalization.
     * This constructors sets a default LRU limit of 100 keys, but this value
     * may be overridden internally as a result of de-externalization.
     */
    public SynchronizedLRUMap()
    {
        this( 100 );
    }


    /**
     * Create a new LRUMap with a maximum capacity of <i>i</i>. Once <i>i</i>
     * capacity is achieved, subsequent gets and puts will push keys out of the
     * map. See .
     * 
     * @param i
     *            Maximum capacity of the LRUMap
     */
    public SynchronizedLRUMap( int i )
    {
        super( i );
        maximumSize = i;
    }


    /**
     * <p>
     * Get the value for a key from the Map. The key will be promoted to the
     * Most Recently Used position. Note that get(Object) operations will modify
     * the underlying Collection. Calling get(Object) inside of an iteration
     * over keys, values, etc. is currently unsupported.
     * </p>
     * 
     * @param key
     *            Key to retrieve
     * @return Returns the value. Returns null if the key has a null value <i>or</i>
     *         if the key has no value.
     */
    public synchronized Object get( Object key )
    {
        if ( !containsKey( key ) )
        {
            return null;
        }

        Object value = remove( key );
        super.put( key, value );
        return value;
    }


    /**
     * <p>
     * Removes the key and its Object from the Map.
     * </p>
     * <p>
     * (Note: this may result in the "Least Recently Used" object being removed
     * from the Map. In that case, the removeLRU() method is called. See javadoc
     * for removeLRU() for more details.)
     * </p>
     * 
     * @param key
     *            Key of the Object to add.
     * @param value
     *            Object to add
     * @return Former value of the key
     */
    public Object put( Object key, Object value )
    {

        int mapSize = size();
        Object retval = null;

        if ( mapSize >= maximumSize )
        {
            synchronized ( this )
            {
                // don't retire LRU if you are just
                // updating an existing key
                if ( !containsKey( key ) )
                {
                    // lets retire the least recently used item in the cache
                    removeLRU();
                }

                retval = super.put( key, value );
            }
        }
        else
        {
            synchronized ( this )
            {
                retval = super.put( key, value );
            }
        }

        return retval;
    }


    /**
     * This method is used internally by the class for finding and removing the
     * LRU Object.
     */
    private void removeLRU()
    {
        Object key = getFirstKey();
        // be sure to call super.get(key), or you're likely to
        // get infinite promotion recursion
        super.get( key );

        remove( key );
    }


    // Properties
    // -------------------------------------------------------------------------
    /**
     * Getter for property maximumSize.
     * 
     * @return Value of property maximumSize.
     */
    public int getMaximumSize()
    {
        return maximumSize;
    }


    /**
     * Setter for property maximumSize.
     * 
     * @param maximumSize
     *            New value of property maximumSize.
     */
    public void setMaximumSize( int maximumSize )
    {
        synchronized ( this )
        {
            this.maximumSize = maximumSize;

            while ( size() > maximumSize )
            {
                removeLRU();
            }
        }
    }
}
