pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / src / java / org / apache / lucene / search / CachingSpanFilter.java
diff --git a/lucene-java-3.5.0/lucene/src/java/org/apache/lucene/search/CachingSpanFilter.java b/lucene-java-3.5.0/lucene/src/java/org/apache/lucene/search/CachingSpanFilter.java
new file mode 100644 (file)
index 0000000..79bd609
--- /dev/null
@@ -0,0 +1,109 @@
+package org.apache.lucene.search;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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 org.apache.lucene.index.IndexReader;
+
+import java.io.IOException;
+
+/**
+ * Wraps another SpanFilter's result and caches it.  The purpose is to allow
+ * filters to simply filter, and then wrap with this class to add caching.
+ */
+public class CachingSpanFilter extends SpanFilter {
+  private SpanFilter filter;
+
+  /**
+   * A transient Filter cache (package private because of test)
+   */
+  private final CachingWrapperFilter.FilterCache<SpanFilterResult> cache;
+
+  /**
+   * New deletions always result in a cache miss, by default
+   * ({@link CachingWrapperFilter.DeletesMode#RECACHE}.
+   * @param filter Filter to cache results of
+   */
+  public CachingSpanFilter(SpanFilter filter) {
+    this(filter, CachingWrapperFilter.DeletesMode.RECACHE);
+  }
+
+  /**
+   * @param filter Filter to cache results of
+   * @param deletesMode See {@link CachingWrapperFilter.DeletesMode}
+   */
+  public CachingSpanFilter(SpanFilter filter, CachingWrapperFilter.DeletesMode deletesMode) {
+    this.filter = filter;
+    if (deletesMode == CachingWrapperFilter.DeletesMode.DYNAMIC) {
+      throw new IllegalArgumentException("DeletesMode.DYNAMIC is not supported");
+    }
+    this.cache = new CachingWrapperFilter.FilterCache<SpanFilterResult>(deletesMode) {
+      @Override
+      protected SpanFilterResult mergeDeletes(final IndexReader reader, final SpanFilterResult value) {
+        throw new IllegalStateException("DeletesMode.DYNAMIC is not supported");
+      }
+    };
+  }
+
+  @Override
+  public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
+    SpanFilterResult result = getCachedResult(reader);
+    return result != null ? result.getDocIdSet() : null;
+  }
+  
+  // for testing
+  int hitCount, missCount;
+
+  private SpanFilterResult getCachedResult(IndexReader reader) throws IOException {
+
+    final Object coreKey = reader.getCoreCacheKey();
+    final Object delCoreKey = reader.hasDeletions() ? reader.getDeletesCacheKey() : coreKey;
+
+    SpanFilterResult result = cache.get(reader, coreKey, delCoreKey);
+    if (result != null) {
+      hitCount++;
+      return result;
+    }
+
+    missCount++;
+    result = filter.bitSpans(reader);
+
+    cache.put(coreKey, delCoreKey, result);
+    return result;
+  }
+
+
+  @Override
+  public SpanFilterResult bitSpans(IndexReader reader) throws IOException {
+    return getCachedResult(reader);
+  }
+
+  @Override
+  public String toString() {
+    return "CachingSpanFilter("+filter+")";
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (!(o instanceof CachingSpanFilter)) return false;
+    return this.filter.equals(((CachingSpanFilter)o).filter);
+  }
+
+  @Override
+  public int hashCode() {
+    return filter.hashCode() ^ 0x1117BF25;
+  }
+}