Index: src/java/org/apache/lucene/search/CachingWrapperFilter.java =================================================================== --- src/java/org/apache/lucene/search/CachingWrapperFilter.java (revision 814707) +++ src/java/org/apache/lucene/search/CachingWrapperFilter.java (working copy) @@ -19,6 +19,7 @@ import org.apache.lucene.index.IndexReader; import org.apache.lucene.util.DocIdBitSet; +import org.apache.lucene.util.OpenBitSet; import java.util.BitSet; import java.util.WeakHashMap; import java.util.Map; @@ -30,6 +31,7 @@ */ public class CachingWrapperFilter extends Filter { protected Filter filter; + protected boolean cacheAsOpenBitSet = true; /** * A transient Filter cache. @@ -42,6 +44,20 @@ public CachingWrapperFilter(Filter filter) { this.filter = filter; } + + /** + * You can specify if the wrapper should cache all DocIdSet that are not implemented by {@link OpenBitSet} + * or {@link DocIdBitSet} as such ones. This defaults to true. + * Set this to false if you have a very special DocIdSet implementation that is easily cacheable. + */ + public void setCacheAsOpenBitSet(boolean value) { + cacheAsOpenBitSet = value; + } + + /** @see #setCacheAsOpenBitSet */ + public boolean getCacheAsOpenBitSet() { + return cacheAsOpenBitSet; + } /** * @deprecated Use {@link #getDocIdSet(IndexReader)} instead. @@ -75,10 +91,22 @@ /** Provide the DocIdSet to be cached, using the DocIdSet provided * by the wrapped Filter. - * This implementation returns the given DocIdSet. + * This implementation returns the given {@link DocIdSet}, if {@link #getCacheAsOpenBitSet} + * returns false. The default is to wrap all {@link DocIdSet}s, that are not implemented + * by {@link OpenBitSet} or {@link DocIdBitSet}. */ - protected DocIdSet docIdSetToCache(DocIdSet docIdSet, IndexReader reader) { - return docIdSet; + protected DocIdSet docIdSetToCache(DocIdSet docIdSet, IndexReader reader) throws IOException { + if (cacheAsOpenBitSet && !(docIdSet instanceof OpenBitSet || docIdSet instanceof DocIdBitSet)) { + final OpenBitSet bits = new OpenBitSet(reader.maxDoc()); + final DocIdSetIterator it = docIdSet.iterator(); + int doc; + while ((doc = it.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) { + bits.fastSet(doc); + } + return bits; + } else { + return docIdSet; + } } public DocIdSet getDocIdSet(IndexReader reader) throws IOException {