diff --git a/src/main/java/org/elasticsearch/common/lucene/docset/DocSets.java b/src/main/java/org/elasticsearch/common/lucene/docset/DocSets.java index 3bb3edb94e3..5ed4385aa26 100644 --- a/src/main/java/org/elasticsearch/common/lucene/docset/DocSets.java +++ b/src/main/java/org/elasticsearch/common/lucene/docset/DocSets.java @@ -24,6 +24,7 @@ import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.util.FixedBitSet; import org.apache.lucene.util.OpenBitSet; +import org.elasticsearch.common.Nullable; import java.io.IOException; @@ -116,22 +117,40 @@ public class DocSets { /** * Returns a cacheable version of the doc id set (might be the same instance provided as a parameter). */ - public static DocSet cacheable(IndexReader reader, DocIdSet docIdSet) throws IOException { - if (docIdSet == null) { + public static DocSet cacheable(IndexReader reader, @Nullable DocIdSet set) throws IOException { + if (set == null) { return DocSet.EMPTY_DOC_SET; - } else if (docIdSet.isCacheable() && (docIdSet instanceof DocSet)) { - return (DocSet) docIdSet; - } else if (docIdSet instanceof FixedBitSet) { - return new FixedBitDocSet((FixedBitSet) docIdSet); - } else if (docIdSet instanceof OpenBitSet) { - return new OpenBitDocSet((OpenBitSet) docIdSet); - } else { - final DocIdSetIterator it = docIdSet.iterator(); - // null is allowed to be returned by iterator(), - // in this case we wrap with the empty set, - // which is cacheable. - return (it == null) ? DocSet.EMPTY_DOC_SET : new FixedBitDocSet(createFixedBitSet(it, reader.maxDoc())); } + if (set == DocIdSet.EMPTY_DOCIDSET) { + return DocSet.EMPTY_DOC_SET; + } + + DocIdSetIterator it = set.iterator(); + if (it == null) { + return DocSet.EMPTY_DOC_SET; + } + int doc = it.nextDoc(); + if (doc == DocIdSetIterator.NO_MORE_DOCS) { + return DocSet.EMPTY_DOC_SET; + } + + if (set.isCacheable() && (set instanceof DocSet)) { + return (DocSet) set; + } + if (set instanceof FixedBitSet) { + return new FixedBitDocSet((FixedBitSet) set); + } + if (set instanceof OpenBitSet) { + return new OpenBitDocSet((OpenBitSet) set); + } + + // work with the iterator... + FixedBitSet fixedBitSet = new FixedBitSet(reader.maxDoc()); + fixedBitSet.set(doc); + while ((doc = it.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) { + fixedBitSet.set(doc); + } + return new FixedBitDocSet(fixedBitSet); } private DocSets() { diff --git a/src/main/java/org/elasticsearch/index/cache/filter/support/FilterCacheValue.java b/src/main/java/org/elasticsearch/index/cache/filter/support/FilterCacheValue.java index 5593b2b2d06..87f5579eb94 100644 --- a/src/main/java/org/elasticsearch/index/cache/filter/support/FilterCacheValue.java +++ b/src/main/java/org/elasticsearch/index/cache/filter/support/FilterCacheValue.java @@ -19,14 +19,6 @@ package org.elasticsearch.index.cache.filter.support; -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.search.DocIdSet; -import org.apache.lucene.search.DocIdSetIterator; -import org.elasticsearch.common.lucene.docset.DocSet; -import org.elasticsearch.common.lucene.docset.DocSets; - -import java.io.IOException; - public class FilterCacheValue { private final T value; @@ -38,24 +30,4 @@ public class FilterCacheValue { public T value() { return value; } - - - public static DocSet cacheable(IndexReader reader, DocIdSet set) throws IOException { - if (set == null) { - return DocSet.EMPTY_DOC_SET; - } - if (set == DocIdSet.EMPTY_DOCIDSET) { - return DocSet.EMPTY_DOC_SET; - } - - DocIdSetIterator it = set.iterator(); - if (it == null) { - return DocSet.EMPTY_DOC_SET; - } - int doc = it.nextDoc(); - if (doc == DocIdSetIterator.NO_MORE_DOCS) { - return DocSet.EMPTY_DOC_SET; - } - return DocSets.cacheable(reader, set); - } } \ No newline at end of file diff --git a/src/main/java/org/elasticsearch/index/cache/filter/weighted/WeightedFilterCache.java b/src/main/java/org/elasticsearch/index/cache/filter/weighted/WeightedFilterCache.java index 5f68be5a840..16a89cb3003 100644 --- a/src/main/java/org/elasticsearch/index/cache/filter/weighted/WeightedFilterCache.java +++ b/src/main/java/org/elasticsearch/index/cache/filter/weighted/WeightedFilterCache.java @@ -30,6 +30,7 @@ import org.apache.lucene.search.Filter; import org.elasticsearch.ElasticSearchException; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.lucene.docset.DocSet; +import org.elasticsearch.common.lucene.docset.DocSets; import org.elasticsearch.common.lucene.search.NoCacheFilter; import org.elasticsearch.common.metrics.CounterMetric; import org.elasticsearch.common.metrics.MeanMetric; @@ -173,7 +174,7 @@ public class WeightedFilterCache extends AbstractIndexComponent implements Filte } DocIdSet docIdSet = filter.getDocIdSet(reader); - DocSet docSet = FilterCacheValue.cacheable(reader, docIdSet); + DocSet docSet = DocSets.cacheable(reader, docIdSet); cacheValue = new FilterCacheValue(docSet); // we might put the same one concurrently, that's fine, it will be replaced and the removal // will be called