add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / src / java / org / apache / lucene / search / CachingSpanFilter.java
1 package org.apache.lucene.search;
2 /**
3  * Copyright 2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18
19 import org.apache.lucene.index.IndexReader;
20
21 import java.io.IOException;
22
23 /**
24  * Wraps another SpanFilter's result and caches it.  The purpose is to allow
25  * filters to simply filter, and then wrap with this class to add caching.
26  */
27 public class CachingSpanFilter extends SpanFilter {
28   private SpanFilter filter;
29
30   /**
31    * A transient Filter cache (package private because of test)
32    */
33   private final CachingWrapperFilter.FilterCache<SpanFilterResult> cache;
34
35   /**
36    * New deletions always result in a cache miss, by default
37    * ({@link CachingWrapperFilter.DeletesMode#RECACHE}.
38    * @param filter Filter to cache results of
39    */
40   public CachingSpanFilter(SpanFilter filter) {
41     this(filter, CachingWrapperFilter.DeletesMode.RECACHE);
42   }
43
44   /**
45    * @param filter Filter to cache results of
46    * @param deletesMode See {@link CachingWrapperFilter.DeletesMode}
47    */
48   public CachingSpanFilter(SpanFilter filter, CachingWrapperFilter.DeletesMode deletesMode) {
49     this.filter = filter;
50     if (deletesMode == CachingWrapperFilter.DeletesMode.DYNAMIC) {
51       throw new IllegalArgumentException("DeletesMode.DYNAMIC is not supported");
52     }
53     this.cache = new CachingWrapperFilter.FilterCache<SpanFilterResult>(deletesMode) {
54       @Override
55       protected SpanFilterResult mergeDeletes(final IndexReader reader, final SpanFilterResult value) {
56         throw new IllegalStateException("DeletesMode.DYNAMIC is not supported");
57       }
58     };
59   }
60
61   @Override
62   public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
63     SpanFilterResult result = getCachedResult(reader);
64     return result != null ? result.getDocIdSet() : null;
65   }
66   
67   // for testing
68   int hitCount, missCount;
69
70   private SpanFilterResult getCachedResult(IndexReader reader) throws IOException {
71
72     final Object coreKey = reader.getCoreCacheKey();
73     final Object delCoreKey = reader.hasDeletions() ? reader.getDeletesCacheKey() : coreKey;
74
75     SpanFilterResult result = cache.get(reader, coreKey, delCoreKey);
76     if (result != null) {
77       hitCount++;
78       return result;
79     }
80
81     missCount++;
82     result = filter.bitSpans(reader);
83
84     cache.put(coreKey, delCoreKey, result);
85     return result;
86   }
87
88
89   @Override
90   public SpanFilterResult bitSpans(IndexReader reader) throws IOException {
91     return getCachedResult(reader);
92   }
93
94   @Override
95   public String toString() {
96     return "CachingSpanFilter("+filter+")";
97   }
98
99   @Override
100   public boolean equals(Object o) {
101     if (!(o instanceof CachingSpanFilter)) return false;
102     return this.filter.equals(((CachingSpanFilter)o).filter);
103   }
104
105   @Override
106   public int hashCode() {
107     return filter.hashCode() ^ 0x1117BF25;
108   }
109 }