Index: lucene/src/java/org/apache/lucene/search/FilterManager.java (deleted) =================================================================== Index: lucene/contrib/remote/src/java/org/apache/lucene/search/FilterManager.java =================================================================== --- lucene/contrib/remote/src/java/org/apache/lucene/search/FilterManager.java (revision 1052924) +++ lucene/contrib/remote/src/java/org/apache/lucene/search/FilterManager.java (working copy) @@ -17,15 +17,10 @@ * limitations under the License. */ -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.Map; -import java.util.TreeSet; +import java.util.Map.Entry; -import org.apache.lucene.util.ThreadInterruptedException; - /** * Filter caching singleton. It can be used * to save filters locally for reuse. @@ -34,27 +29,18 @@ * * Also could be used as a persistent storage for any filter as long as the * filter provides a proper hashCode(), as that is used as the key in the cache. - * - * The cache is periodically cleaned up from a separate thread to ensure the - * cache doesn't exceed the maximum size. */ public class FilterManager { protected static FilterManager manager; /** The default maximum number of Filters in the cache */ - protected static final int DEFAULT_CACHE_CLEAN_SIZE = 100; - /** The default frequency of cache cleanup */ - protected static final long DEFAULT_CACHE_SLEEP_TIME = 1000 * 60 * 10; + protected static final int DEFAULT_CACHE_SIZE = 100; /** The cache itself */ - protected Map cache; + protected Map cache; /** Maximum allowed cache size */ - protected int cacheCleanSize; - /** Cache cleaning frequency */ - protected long cleanSleepTime; - /** Cache cleaner that runs in a separate thread */ - protected FilterCleaner filterCleaner; + protected int cacheSize = DEFAULT_CACHE_SIZE; public synchronized static FilterManager getInstance() { if (manager == null) { @@ -67,34 +53,23 @@ * Sets up the FilterManager singleton. */ protected FilterManager() { - cache = new HashMap(); - cacheCleanSize = DEFAULT_CACHE_CLEAN_SIZE; // Let the cache get to 100 items - cleanSleepTime = DEFAULT_CACHE_SLEEP_TIME; // 10 minutes between cleanings - - filterCleaner = new FilterCleaner(); - Thread fcThread = new Thread(filterCleaner); - // set to be a Daemon so it doesn't have to be stopped - fcThread.setDaemon(true); - fcThread.start(); + cache = new LinkedHashMap() { + @Override + protected boolean removeEldestEntry(Entry entry) { + return size() > cacheSize; + } + }; } /** * Sets the max size that cache should reach before it is cleaned up * @param cacheCleanSize maximum allowed cache size */ - public void setCacheSize(int cacheCleanSize) { - this.cacheCleanSize = cacheCleanSize; + public synchronized void setCacheSize(int cacheSize) { + this.cacheSize = cacheSize; } /** - * Sets the cache cleaning frequency in milliseconds. - * @param cleanSleepTime cleaning frequency in milliseconds - */ - public void setCleanThreadSleepTime(long cleanSleepTime) { - this.cleanSleepTime = cleanSleepTime; - } - - /** * Returns the cached version of the filter. Allows the caller to pass up * a small filter but this will keep a persistent version around and allow * the caching filter to do its job. @@ -102,102 +77,14 @@ * @param filter The input filter * @return The cached version of the filter */ - public Filter getFilter(Filter filter) { - synchronized(cache) { - FilterItem fi = null; - fi = cache.get(Integer.valueOf(filter.hashCode())); - if (fi != null) { - fi.timestamp = new Date().getTime(); - return fi.filter; - } - cache.put(Integer.valueOf(filter.hashCode()), new FilterItem(filter)); + public synchronized Filter getFilter(Filter filter) { + Filter fi = null; + fi = cache.get(Integer.valueOf(filter.hashCode())); + if (fi != null) { + return fi; + } else { + cache.put(Integer.valueOf(filter.hashCode()), filter); return filter; } } - - /** - * Holds the filter and the last time the filter was used, to make LRU-based - * cache cleaning possible. - * TODO: Clean this up when we switch to Java 1.5 - */ - protected class FilterItem { - public Filter filter; - public long timestamp; - - public FilterItem (Filter filter) { - this.filter = filter; - this.timestamp = new Date().getTime(); - } - } - - - /** - * Keeps the cache from getting too big. - * If we were using Java 1.5, we could use LinkedHashMap and we would not need this thread - * to clean out the cache. - * - * The SortedSet sortedFilterItems is used only to sort the items from the cache, - * so when it's time to clean up we have the TreeSet sort the FilterItems by - * timestamp. - * - * Removes 1.5 * the numbers of items to make the cache smaller. - * For example: - * If cache clean size is 10, and the cache is at 15, we would remove (15 - 10) * 1.5 = 7.5 round up to 8. - * This way we clean the cache a bit more, and avoid having the cache cleaner having to do it frequently. - */ - protected class FilterCleaner implements Runnable { - - private boolean running = true; - private TreeSet> sortedFilterItems; - - public FilterCleaner() { - sortedFilterItems = new TreeSet>(new Comparator>() { - public int compare(Map.Entry a, Map.Entry b) { - FilterItem fia = a.getValue(); - FilterItem fib = b.getValue(); - if ( fia.timestamp == fib.timestamp ) { - return 0; - } - // smaller timestamp first - if ( fia.timestamp < fib.timestamp ) { - return -1; - } - // larger timestamp last - return 1; - - } - }); - } - - public void run () { - while (running) { - - // sort items from oldest to newest - // we delete the oldest filters - if (cache.size() > cacheCleanSize) { - // empty the temporary set - sortedFilterItems.clear(); - synchronized (cache) { - sortedFilterItems.addAll(cache.entrySet()); - Iterator> it = sortedFilterItems.iterator(); - int numToDelete = (int) ((cache.size() - cacheCleanSize) * 1.5); - int counter = 0; - // loop over the set and delete all of the cache entries not used in a while - while (it.hasNext() && counter++ < numToDelete) { - Map.Entry entry = it.next(); - cache.remove(entry.getKey()); - } - } - // empty the set so we don't tie up the memory - sortedFilterItems.clear(); - } - // take a nap - try { - Thread.sleep(cleanSleepTime); - } catch (InterruptedException ie) { - throw new ThreadInterruptedException(ie); - } - } - } - } }