159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.terrain.geomipmap;
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// Copyright 2007 Christian d'Heureuse, Inventec Informatik AG, Zurich,
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// Switzerland
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// www.source-code.biz, www.inventec.ch/chdh
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// This module is multi-licensed and may be used under the terms
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// of any of the following licenses:
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// EPL, Eclipse Public License, V1.0 or later, http://www.eclipse.org/legal
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// LGPL, GNU Lesser General Public License, V2 or later,
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// http://www.gnu.org/licenses/lgpl.html
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// GPL, GNU General Public License, V2 or later,
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// http://www.gnu.org/licenses/gpl.html
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// AL, Apache License, V2.0 or later, http://www.apache.org/licenses
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// BSD, BSD License, http://www.opensource.org/licenses/bsd-license.php
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// Please contact the author if you need another license.
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// This module is provided "as is", without warranties of any kind.
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.ArrayList;
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.Collection;
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.LinkedHashMap;
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.Map;
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * An LRU cache, based on <code>LinkedHashMap</code>.
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p>
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This cache has a fixed maximum number of elements (<code>cacheSize</code>).
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * If the cache is full and another entry is added, the LRU (least recently
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * used) entry is dropped.
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p>
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This class is thread-safe. All methods of this class are synchronized.
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p>
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Author: Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland<br>
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Multi-licensed: EPL / LGPL / GPL / AL / BSD.
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class LRUCache<K, V> {
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final float hashTableLoadFactor = 0.75f;
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private LinkedHashMap<K, V> map;
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private int cacheSize;
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new LRU cache.
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param cacheSize
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the maximum number of entries that will be kept in this cache.
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public LRUCache(int cacheSize) {
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.cacheSize = cacheSize;
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int hashTableCapacity = (int) Math.ceil(cacheSize / LRUCache.hashTableLoadFactor) + 1;
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.map = new LinkedHashMap<K, V>(hashTableCapacity, LRUCache.hashTableLoadFactor, true) {
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // (an anonymous inner class)
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            private static final long serialVersionUID = 1;
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            @Override
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return this.size() > LRUCache.this.cacheSize;
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        };
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Retrieves an entry from the cache.<br>
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The retrieved entry becomes the MRU (most recently used) entry.
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param key
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the key whose associated value is to be returned.
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the value associated to this key, or null if no value with this
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *         key exists in the cache.
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public synchronized V get(K key) {
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return this.map.get(key);
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Adds an entry to this cache.
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The new entry becomes the MRU (most recently used) entry.
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * If an entry with the specified key already exists in the cache, it is
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * replaced by the new entry.
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * If the cache is full, the LRU (least recently used) entry is removed from
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the cache.
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param key
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the key with which the specified value is to be associated.
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param value
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            a value to be associated with the specified key.
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public synchronized void put(K key, V value) {
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.map.put(key, value);
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Clears the cache.
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public synchronized void clear() {
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.map.clear();
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns the number of used entries in the cache.
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the number of entries currently in the cache.
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public synchronized int usedEntries() {
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return this.map.size();
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns a <code>Collection</code> that contains a copy of all cache
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * entries.
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return a <code>Collection</code> with a copy of the cache content.
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public synchronized Collection<Map.Entry<K, V>> getAll() {
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return new ArrayList<Map.Entry<K, V>>(this.map.entrySet());
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta} // end class LRUCache
123