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

org.apache.lucene.facet.taxonomy.LRUHashMap Maven / Gradle / Ivy

There is a newer version: 9.11.1
Show newest version
/*
 * 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.lucene.facet.taxonomy;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * LRUHashMap is an extension of Java's HashMap, which has a bounded size();
 * When it reaches that size, each time a new element is added, the least
 * recently used (LRU) entry is removed.
 * 

* Java makes it very easy to implement LRUHashMap - all its functionality is * already available from {@link java.util.LinkedHashMap}, and we just need to * configure that properly. *

* Note that like HashMap, LRUHashMap is unsynchronized, and the user MUST * synchronize the access to it if used from several threads. Moreover, while * with HashMap this is only a concern if one of the threads is modifies the * map, with LURHashMap every read is a modification (because the LRU order * needs to be remembered) so proper synchronization is always necessary. *

* With the usual synchronization mechanisms available to the user, this * unfortunately means that LRUHashMap will probably perform sub-optimally under * heavy contention: while one thread uses the hash table (reads or writes), any * other thread will be blocked from using it - or even just starting to use it * (e.g., calculating the hash function). A more efficient approach would be not * to use LinkedHashMap at all, but rather to use a non-locking (as much as * possible) thread-safe solution, something along the lines of * java.util.concurrent.ConcurrentHashMap (though that particular class does not * support the additional LRU semantics, which will need to be added separately * using a concurrent linked list or additional storage of timestamps (in an * array or inside the entry objects), or whatever). * * @lucene.experimental */ public class LRUHashMap extends LinkedHashMap { private int maxSize; /** * Create a new hash map with a bounded size and with least recently * used entries removed. * @param maxSize * the maximum size (in number of entries) to which the map can grow * before the least recently used entries start being removed.
* Setting maxSize to a very large value, like * {@link Integer#MAX_VALUE} is allowed, but is less efficient than * using {@link java.util.HashMap} because our class needs * to keep track of the use order (via an additional doubly-linked * list) which is not used when the map's size is always below the * maximum size. */ public LRUHashMap(int maxSize) { super(16, 0.75f, true); this.maxSize = maxSize; } /** * Return the max size */ public int getMaxSize() { return maxSize; } /** * setMaxSize() allows changing the map's maximal number of elements * which was defined at construction time. *

* Note that if the map is already larger than maxSize, the current * implementation does not shrink it (by removing the oldest elements); * Rather, the map remains in its current size as new elements are * added, and will only start shrinking (until settling again on the * give maxSize) if existing elements are explicitly deleted. */ public void setMaxSize(int maxSize) { this.maxSize = maxSize; } // We override LinkedHashMap's removeEldestEntry() method. This method // is called every time a new entry is added, and if we return true // here, the eldest element will be deleted automatically. In our case, // we return true if the size of the map grew beyond our limit - ignoring // what is that eldest element that we'll be deleting. @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > maxSize; } @SuppressWarnings("unchecked") @Override public LRUHashMap clone() { return (LRUHashMap) super.clone(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy