~slub.team/goobi-indexserver/3.x

« back to all changes in this revision

Viewing changes to lucene/src/java/org/apache/lucene/search/FilterManager.java

  • Committer: Sebastian Meyer
  • Date: 2012-08-03 09:12:40 UTC
  • Revision ID: sebastian.meyer@slub-dresden.de-20120803091240-x6861b0vabq1xror
Remove Lucene and Solr source code and add patches instead
Fix Bug #985487: Auto-suggestion for the search interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
package org.apache.lucene.search;
2
 
 
3
 
/**
4
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
5
 
 * contributor license agreements.  See the NOTICE file distributed with
6
 
 * this work for additional information regarding copyright ownership.
7
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
8
 
 * (the "License"); you may not use this file except in compliance with
9
 
 * the License.  You may obtain a copy of the License at
10
 
 *
11
 
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 
 *
13
 
 * Unless required by applicable law or agreed to in writing, software
14
 
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 
 * See the License for the specific language governing permissions and
17
 
 * limitations under the License.
18
 
 */
19
 
 
20
 
import java.util.Comparator;
21
 
import java.util.Date;
22
 
import java.util.HashMap;
23
 
import java.util.Iterator;
24
 
import java.util.Map;
25
 
import java.util.TreeSet;
26
 
 
27
 
import org.apache.lucene.util.ThreadInterruptedException;
28
 
 
29
 
/**
30
 
 * Filter caching singleton. It can be used to save filters locally for reuse.
31
 
 * This class makes it possible to cache Filters even when using RMI, as it
32
 
 * keeps the cache on the searcher side of the RMI connection.
33
 
 * 
34
 
 * Also could be used as a persistent storage for any filter as long as the
35
 
 * filter provides a proper hashCode(), as that is used as the key in the cache.
36
 
 * 
37
 
 * The cache is periodically cleaned up from a separate thread to ensure the
38
 
 * cache doesn't exceed the maximum size.
39
 
 * 
40
 
 * @deprecated used by remote package which is deprecated as well. You should
41
 
 *             use {@link CachingWrapperFilter} if you wish to cache
42
 
 *             {@link Filter}s.
43
 
 */
44
 
@Deprecated
45
 
public class FilterManager {
46
 
 
47
 
  protected static FilterManager manager;
48
 
  
49
 
  /** The default maximum number of Filters in the cache */
50
 
  protected static final int  DEFAULT_CACHE_CLEAN_SIZE = 100;
51
 
  /** The default frequency of cache cleanup */
52
 
  protected static final long DEFAULT_CACHE_SLEEP_TIME = 1000 * 60 * 10;
53
 
 
54
 
  /** The cache itself */
55
 
  protected Map<Integer,FilterItem>           cache;
56
 
  /** Maximum allowed cache size */
57
 
  protected int           cacheCleanSize;
58
 
  /** Cache cleaning frequency */
59
 
  protected long          cleanSleepTime;
60
 
  /** Cache cleaner that runs in a separate thread */
61
 
  protected FilterCleaner filterCleaner;
62
 
 
63
 
  public synchronized static FilterManager getInstance() {
64
 
    if (manager == null) {
65
 
      manager = new FilterManager();
66
 
    }
67
 
    return manager;
68
 
  }
69
 
 
70
 
  /**
71
 
   * Sets up the FilterManager singleton.
72
 
   */
73
 
  protected FilterManager() {
74
 
    cache            = new HashMap<Integer,FilterItem>();
75
 
    cacheCleanSize   = DEFAULT_CACHE_CLEAN_SIZE; // Let the cache get to 100 items
76
 
    cleanSleepTime   = DEFAULT_CACHE_SLEEP_TIME; // 10 minutes between cleanings
77
 
 
78
 
    filterCleaner   = new FilterCleaner();
79
 
    Thread fcThread = new Thread(filterCleaner);
80
 
    // set to be a Daemon so it doesn't have to be stopped
81
 
    fcThread.setDaemon(true);
82
 
    fcThread.start();
83
 
  }
84
 
  
85
 
  /**
86
 
   * Sets the max size that cache should reach before it is cleaned up
87
 
   * @param cacheCleanSize maximum allowed cache size
88
 
   */
89
 
  public void setCacheSize(int cacheCleanSize) {
90
 
    this.cacheCleanSize = cacheCleanSize;
91
 
  }
92
 
 
93
 
  /**
94
 
   * Sets the cache cleaning frequency in milliseconds.
95
 
   * @param cleanSleepTime cleaning frequency in milliseconds
96
 
   */
97
 
  public void setCleanThreadSleepTime(long cleanSleepTime) {
98
 
    this.cleanSleepTime  = cleanSleepTime;
99
 
  }
100
 
 
101
 
  /**
102
 
   * Returns the cached version of the filter.  Allows the caller to pass up
103
 
   * a small filter but this will keep a persistent version around and allow
104
 
   * the caching filter to do its job.
105
 
   * 
106
 
   * @param filter The input filter
107
 
   * @return The cached version of the filter
108
 
   */
109
 
  public Filter getFilter(Filter filter) {
110
 
    synchronized(cache) {
111
 
      FilterItem fi = null;
112
 
      fi = cache.get(Integer.valueOf(filter.hashCode()));
113
 
      if (fi != null) {
114
 
        fi.timestamp = new Date().getTime();
115
 
        return fi.filter;
116
 
      }
117
 
      cache.put(Integer.valueOf(filter.hashCode()), new FilterItem(filter));
118
 
      return filter;
119
 
    }
120
 
  }
121
 
 
122
 
  /**
123
 
   * Holds the filter and the last time the filter was used, to make LRU-based
124
 
   * cache cleaning possible.
125
 
   * TODO: Clean this up when we switch to Java 1.5
126
 
   */
127
 
  protected class FilterItem {
128
 
    public Filter filter;
129
 
    public long   timestamp;
130
 
 
131
 
    public FilterItem (Filter filter) {        
132
 
      this.filter = filter;
133
 
      this.timestamp = new Date().getTime();
134
 
    }
135
 
  }
136
 
 
137
 
 
138
 
  /**
139
 
   * Keeps the cache from getting too big.
140
 
   * If we were using Java 1.5, we could use LinkedHashMap and we would not need this thread
141
 
   * to clean out the cache.
142
 
   * 
143
 
   * The SortedSet sortedFilterItems is used only to sort the items from the cache,
144
 
   * so when it's time to clean up we have the TreeSet sort the FilterItems by
145
 
   * timestamp.
146
 
   * 
147
 
   * Removes 1.5 * the numbers of items to make the cache smaller.
148
 
   * For example:
149
 
   * 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.
150
 
   * This way we clean the cache a bit more, and avoid having the cache cleaner having to do it frequently.
151
 
   */
152
 
  protected class FilterCleaner implements Runnable  {
153
 
 
154
 
    private boolean running = true;
155
 
    private TreeSet<Map.Entry<Integer,FilterItem>> sortedFilterItems;
156
 
 
157
 
    public FilterCleaner() {
158
 
      sortedFilterItems = new TreeSet<Map.Entry<Integer,FilterItem>>(new Comparator<Map.Entry<Integer,FilterItem>>() {
159
 
        public int compare(Map.Entry<Integer,FilterItem> a, Map.Entry<Integer,FilterItem> b) {
160
 
            FilterItem fia = a.getValue();
161
 
            FilterItem fib = b.getValue();
162
 
            if ( fia.timestamp == fib.timestamp ) {
163
 
              return 0;
164
 
            }
165
 
            // smaller timestamp first
166
 
            if ( fia.timestamp < fib.timestamp ) {
167
 
              return -1;
168
 
            }
169
 
            // larger timestamp last
170
 
            return 1;
171
 
          
172
 
        }
173
 
      });
174
 
    }
175
 
 
176
 
    public void run () {
177
 
      while (running) {
178
 
 
179
 
        // sort items from oldest to newest 
180
 
        // we delete the oldest filters 
181
 
        if (cache.size() > cacheCleanSize) {
182
 
          // empty the temporary set
183
 
          sortedFilterItems.clear();
184
 
          synchronized (cache) {
185
 
            sortedFilterItems.addAll(cache.entrySet());
186
 
            Iterator<Map.Entry<Integer,FilterItem>> it = sortedFilterItems.iterator();
187
 
            int numToDelete = (int) ((cache.size() - cacheCleanSize) * 1.5);
188
 
            int counter = 0;
189
 
            // loop over the set and delete all of the cache entries not used in a while
190
 
            while (it.hasNext() && counter++ < numToDelete) {
191
 
              Map.Entry<Integer,FilterItem> entry = it.next();
192
 
              cache.remove(entry.getKey());
193
 
            }
194
 
          }
195
 
          // empty the set so we don't tie up the memory
196
 
          sortedFilterItems.clear();
197
 
        }
198
 
        // take a nap
199
 
        try {
200
 
          Thread.sleep(cleanSleepTime);
201
 
        } catch (InterruptedException ie) {
202
 
          throw new ThreadInterruptedException(ie);
203
 
        }
204
 
      }
205
 
    }
206
 
  }
207
 
}