All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.twelvemonkeys.util.LRUMap Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2008, Harald Kuhr
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.twelvemonkeys.util;

import java.util.Map;

/**
 * Map implementation with size limit, that keeps its entries in LRU
 * (least recently used) order, also known as access-order.
 * When the size limit is reached, the least recently accessed mappings are
 * removed. The number of mappings to be removed from the map, is
 * controlled by the trim factor.
 * 

*

    *
  • Default size limit is 1000 elements. * See {@link #setMaxSize(int)}/{@link #getMaxSize()}.
  • *
  • Default trim factor is 1% ({@code 0.01f}). * See {@link #setTrimFactor(float)}/{@link #getTrimFactor()}.
  • *
* * @author Harald Kuhr * @version $Id: com/twelvemonkeys/util/LRUMap.java#1 $ */ public class LRUMap extends LinkedMap implements ExpiringMap { private int maxSize = 1000; private float trimFactor = 0.01f; /** * Creates an LRUMap with default max size (1000 entries). * * This is constructor is here to comply with the reccomendations for * "standard" constructors in the {@code Map} interface. * * @see #LRUMap(int) */ public LRUMap() { super(null, true); } /** * Creates an LRUMap with the given max size. * * @param pMaxSize size limit */ public LRUMap(int pMaxSize) { super(null, true); setMaxSize(pMaxSize); } /** * Creates an LRUMap with initial mappings from the given map, * and default max size (1000 entries). * * This is constructor is here to comply with the reccomendations for * "standard" constructors in the {@code Map} interface. * * @param pContents the map whose mappings are to be placed in this map. * May be {@code null}. * * @see #LRUMap(Map, int) */ public LRUMap(Map pContents) { super(pContents, true); } /** * Creates an LRUMap with initial mappings from the given map, * and the given max size. * * @param pContents the map whose mappings are to be placed in this map. * May be {@code null}. * @param pMaxSize size limit */ public LRUMap(Map pContents, int pMaxSize) { super(pContents, true); setMaxSize(pMaxSize); } /** * Creates an LRUMap with initial mappings from the given map, * and the given max size. * * @param pBacking the backing map of this map. Must be either empty, or * the same map as {@code pContents}. * @param pContents the map whose mappings are to be placed in this map. * May be {@code null}. * @param pMaxSize max size */ public LRUMap(Map> pBacking, Map pContents, int pMaxSize) { super(pBacking, pContents, true); setMaxSize(pMaxSize); } /** * Returns the maximum number of mappings in this map. * * @return the size limit */ public int getMaxSize() { return maxSize; } /** * Sets the maximum number of elements in this map. * * If the current size is greater than the new max size, the map will be * trimmed to fit the new max size constraint. * * @see #removeLRU() * * @param pMaxSize new size limit */ public void setMaxSize(int pMaxSize) { if (pMaxSize < 0) { throw new IllegalArgumentException("max size must be positive"); } maxSize = pMaxSize; while(size() > maxSize) { removeLRU(); } } /** * Returns the current trim factor. *

* The trim factor controls how many percent of the maps current size is * reclaimed, when performing an {@code removeLRU} operation. * Defaults to 1% ({@code 0.01f}). * * @return the current trim factor */ public float getTrimFactor() { return trimFactor; } /** * Sets the trim factor. *

* The trim factor controls how many percent of the maps current size is * reclaimed, when performing an {@code removeLRU} operation. * Defaults to 1% ({@code 0.01f}). * * @param pTrimFactor the new trim factor. Acceptable values are between * 0 (inclusive) and 1 (exclusive). * * @see #removeLRU() */ public void setTrimFactor(float pTrimFactor) { if (pTrimFactor < 0f || pTrimFactor >= 1f) { throw new IllegalArgumentException("trim factor must be between 0 and 1"); } trimFactor = pTrimFactor; } /** * always returns {@code false}, and instead invokes {@code removeLRU()} * if {@code size >= maxSize}. */ protected boolean removeEldestEntry(Entry pEldest) { // NOTE: As removeLRU() may remove more than one entry, this is better // than simply removing the eldest entry. if (size() >= maxSize) { removeLRU(); } return false; } protected Entry removeEntry(Entry pEntry) { Entry entry = super.removeEntry(pEntry); processRemoved(pEntry); return entry; } /** * Default implementation does nothing. * May be used by clients as a call-back to notify when mappings expire from * the map. * * @param pRemoved the removed mapping */ public void processRemoved(Entry pRemoved) { } /** * Removes the least recently used mapping(s) from this map. *

* How many mappings are removed from the map, is controlled by the * trim factor. * In any case, at least one mapping will be removed. * * @see #getTrimFactor() */ public void removeLRU() { int removeCount = (int) Math.max((size() * trimFactor), 1); while ((removeCount--) > 0) { removeEntry(head.next); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy