001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.util.collections;
018
019import java.util.LinkedHashMap;
020import java.util.Map;
021
022/**
023 * Holds a map of most recently used items of a given maximum size. Old entries are expired when the
024 * map exceeds that maximum size.
025 * 
026 * @author Jonathan Locke
027 * @param <K>
028 *            key type
029 * @param <V>
030 *            value type
031 */
032public class MostRecentlyUsedMap<K, V> extends LinkedHashMap<K, V>
033{
034        private static final long serialVersionUID = 1L;
035
036        /** Value most recently removed from map */
037        protected V removedValue;
038
039        /** Maximum number of entries allowed in this map */
040        private final int maxEntries;
041
042        /**
043         * Constructor
044         * 
045         * @param maxEntries
046         *            Maximum number of entries allowed in the map
047         */
048        public MostRecentlyUsedMap(final int maxEntries)
049        {
050                super(10, 0.75f, true);
051
052                if (maxEntries <= 0)
053                {
054                        throw new IllegalArgumentException("Must have at least one entry");
055                }
056
057                this.maxEntries = maxEntries;
058        }
059
060        /**
061         * @return Returns the removedValue.
062         */
063        public V getRemovedValue()
064        {
065                return removedValue;
066        }
067
068        /**
069         * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry)
070         */
071        @Override
072        protected boolean removeEldestEntry(final Map.Entry<K, V> eldest)
073        {
074                final boolean remove = size() > maxEntries;
075                // when it should be removed remember the oldest value that will be removed
076                if (remove)
077                {
078                        this.removedValue = eldest.getValue();
079                }
080                else
081                {
082                        removedValue = null;
083                }
084                return remove;
085        }
086}