2 * Created on 25-Jan-2006
4 package org.apache.lucene.xmlparser.builders;
6 import java.util.Map.Entry;
8 import org.apache.lucene.search.CachingWrapperFilter;
9 import org.apache.lucene.search.Filter;
10 import org.apache.lucene.search.Query;
11 import org.apache.lucene.search.QueryWrapperFilter;
12 import org.apache.lucene.xmlparser.DOMUtils;
13 import org.apache.lucene.xmlparser.FilterBuilder;
14 import org.apache.lucene.xmlparser.FilterBuilderFactory;
15 import org.apache.lucene.xmlparser.ParserException;
16 import org.apache.lucene.xmlparser.QueryBuilder;
17 import org.apache.lucene.xmlparser.QueryBuilderFactory;
18 import org.w3c.dom.Element;
20 * Licensed to the Apache Software Foundation (ASF) under one or more
21 * contributor license agreements. See the NOTICE file distributed with
22 * this work for additional information regarding copyright ownership.
23 * The ASF licenses this file to You under the Apache License, Version 2.0
24 * (the "License"); you may not use this file except in compliance with
25 * the License. You may obtain a copy of the License at
27 * http://www.apache.org/licenses/LICENSE-2.0
29 * Unless required by applicable law or agreed to in writing, software
30 * distributed under the License is distributed on an "AS IS" BASIS,
31 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32 * See the License for the specific language governing permissions and
33 * limitations under the License.
36 * Filters are cached in an LRU Cache keyed on the contained query or filter object. Using this will
37 * speed up overall performance for repeated uses of the same expensive query/filter. The sorts of
38 * queries/filters likely to benefit from caching need not necessarily be complex - e.g. simple
39 * TermQuerys with a large DF (document frequency) can be expensive on large indexes.
40 * A good example of this might be a term query on a field with only 2 possible values -
41 * "true" or "false". In a large index, querying or filtering on this field requires reading
42 * millions of document ids from disk which can more usefully be cached as a filter bitset.
44 * For Queries/Filters to be cached and reused the object must implement hashcode and
45 * equals methods correctly so that duplicate queries/filters can be detected in the cache.
47 * The CoreParser.maxNumCachedFilters property can be used to control the size of the LRU
48 * Cache established during the construction of CoreParser instances.
51 public class CachedFilterBuilder implements FilterBuilder {
53 private QueryBuilderFactory queryFactory;
54 private FilterBuilderFactory filterFactory;
56 private LRUCache<Object,Filter> filterCache = null;
58 private int cacheSize;
60 public CachedFilterBuilder(QueryBuilderFactory queryFactory,
61 FilterBuilderFactory filterFactory,int cacheSize)
63 this.queryFactory=queryFactory;
64 this.filterFactory=filterFactory;
65 this.cacheSize=cacheSize;
68 public synchronized Filter getFilter(Element e) throws ParserException
71 Element childElement = DOMUtils.getFirstChildOrFail(e);
73 if (filterCache == null)
75 filterCache = new LRUCache<Object,Filter>(cacheSize);
78 // Test to see if child Element is a query or filter that needs to be
80 QueryBuilder qb = queryFactory.getQueryBuilder(childElement.getNodeName());
81 Object cacheKey = null;
86 q = qb.getQuery(childElement);
90 f = filterFactory.getFilter(childElement);
93 Filter cachedFilter = filterCache.get(cacheKey);
94 if (cachedFilter != null)
96 return cachedFilter; // cache hit
102 cachedFilter = new QueryWrapperFilter(q);
105 cachedFilter = new CachingWrapperFilter(f);
108 filterCache.put(cacheKey, cachedFilter);
112 static class LRUCache<K,V> extends java.util.LinkedHashMap<K,V>
114 public LRUCache(int maxsize)
116 super(maxsize * 4 / 3 + 1, 0.75f, true);
117 this.maxsize = maxsize;
120 protected int maxsize;
123 protected boolean removeEldestEntry(Entry<K,V> eldest)
125 return size() > maxsize;