mirror of https://github.com/apache/lucene.git
remove FilterManager
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1064078 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ad24f6a01f
commit
4aa8a1f179
|
@ -1,203 +0,0 @@
|
||||||
package org.apache.lucene.search;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
import org.apache.lucene.util.ThreadInterruptedException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter caching singleton. It can be used
|
|
||||||
* to save filters locally for reuse.
|
|
||||||
* This class makes it possible to cache Filters even when using RMI, as it
|
|
||||||
* keeps the cache on the searcher side of the RMI connection.
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
/** The cache itself */
|
|
||||||
protected Map<Integer,FilterItem> 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;
|
|
||||||
|
|
||||||
public synchronized static FilterManager getInstance() {
|
|
||||||
if (manager == null) {
|
|
||||||
manager = new FilterManager();
|
|
||||||
}
|
|
||||||
return manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets up the FilterManager singleton.
|
|
||||||
*/
|
|
||||||
protected FilterManager() {
|
|
||||||
cache = new HashMap<Integer,FilterItem>();
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @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));
|
|
||||||
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<Map.Entry<Integer,FilterItem>> sortedFilterItems;
|
|
||||||
|
|
||||||
public FilterCleaner() {
|
|
||||||
sortedFilterItems = new TreeSet<Map.Entry<Integer,FilterItem>>(new Comparator<Map.Entry<Integer,FilterItem>>() {
|
|
||||||
public int compare(Map.Entry<Integer,FilterItem> a, Map.Entry<Integer,FilterItem> 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<Map.Entry<Integer,FilterItem>> 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<Integer,FilterItem> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue