blob: f93c5ed3be40f8814a9d4bd0d592cbb179049132 [file] [log] [blame]
Index: lucene/spatial/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java
===================================================================
--- lucene/spatial/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java (revision 1690252)
+++ lucene/spatial/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java (working copy)
@@ -38,9 +38,8 @@
import org.apache.lucene.spatial.prefix.AbstractVisitingPrefixTreeFilter;
import org.apache.lucene.spatial.prefix.tree.Cell;
import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.spatial.util.BitDocIdSetBuilder;
-import org.apache.lucene.util.BitDocIdSet;
import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.DocIdSetBuilder;
/**
* A spatial Intersects predicate that distinguishes an approximated match from an exact match based on which cells
@@ -103,16 +102,16 @@
if (approxDISI == null) {
return null;
}
- final Bits exactDocBits;
+ final DocIdSetIterator exactIterator;
if (result.exactDocIdSet != null) {
// If both sets are the same, there's nothing to verify; we needn't return a TwoPhaseIterator
- if (result.approxDocIdSet.equals(result.exactDocIdSet)) {
+ if (result.approxDocIdSet == result.exactDocIdSet) {
return new ConstantScoreScorer(this, score(), approxDISI);
}
- exactDocBits = result.exactDocIdSet.bits();
- assert exactDocBits != null;
+ exactIterator = result.exactDocIdSet.iterator();
+ assert exactIterator != null;
} else {
- exactDocBits = null;
+ exactIterator = null;
}
final FunctionValues predFuncValues = predicateValueSource.getValues(valueSourceContext, context);
@@ -120,11 +119,17 @@
final TwoPhaseIterator twoPhaseIterator = new TwoPhaseIterator(approxDISI) {
@Override
public boolean matches() throws IOException {
- if (exactDocBits != null && exactDocBits.get(approxDISI.docID())) {
- return true;
+ final int doc = approxDISI.docID();
+ if (exactIterator != null) {
+ if (exactIterator.docID() < doc) {
+ exactIterator.advance(doc);
+ }
+ if (exactIterator.docID() == doc) {
+ return true;
+ }
}
- return predFuncValues.boolVal(approxDISI.docID());
+ return predFuncValues.boolVal(doc);
}
};
@@ -153,10 +158,12 @@
// TODO consider if IntersectsPrefixTreeFilter should simply do this and provide both sets
class IntersectsDifferentiatingVisitor extends VisitorTemplate {
- BitDocIdSetBuilder approxBuilder = new BitDocIdSetBuilder(maxDoc);
- BitDocIdSetBuilder exactBuilder = new BitDocIdSetBuilder(maxDoc);
- BitDocIdSet exactDocIdSet;
- BitDocIdSet approxDocIdSet;
+ DocIdSetBuilder approxBuilder = new DocIdSetBuilder(maxDoc);
+ DocIdSetBuilder exactBuilder = new DocIdSetBuilder(maxDoc);
+ boolean approxIsEmpty = true;
+ boolean exactIsEmpty = true;
+ DocIdSet exactDocIdSet;
+ DocIdSet approxDocIdSet;
public IntersectsDifferentiatingVisitor(LeafReaderContext context, Bits acceptDocs) throws IOException {
super(context, acceptDocs);
@@ -168,12 +175,16 @@
@Override
protected DocIdSet finish() throws IOException {
- exactDocIdSet = exactBuilder.build();
- if (approxBuilder.isDefinitelyEmpty()) {
+ if (exactIsEmpty) {
+ exactDocIdSet = null;
+ } else {
+ exactDocIdSet = exactBuilder.build();
+ }
+ if (approxIsEmpty) {
approxDocIdSet = exactDocIdSet;//optimization
} else {
if (exactDocIdSet != null) {
- approxBuilder.or(exactDocIdSet.iterator());
+ approxBuilder.add(exactDocIdSet.iterator());
}
approxDocIdSet = approxBuilder.build();
}
@@ -183,9 +194,11 @@
@Override
protected boolean visitPrefix(Cell cell) throws IOException {
if (cell.getShapeRel() == SpatialRelation.WITHIN) {
+ exactIsEmpty = false;
collectDocs(exactBuilder);//note: we'll add exact to approx on finish()
return false;
} else if (cell.getLevel() == detailLevel) {
+ approxIsEmpty = false;
collectDocs(approxBuilder);
return false;
}
@@ -195,8 +208,10 @@
@Override
protected void visitLeaf(Cell cell) throws IOException {
if (cell.getShapeRel() == SpatialRelation.WITHIN) {
+ exactIsEmpty = false;
collectDocs(exactBuilder);//note: we'll add exact to approx on finish()
} else {
+ approxIsEmpty = false;
collectDocs(approxBuilder);
}
}
Index: lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeFilter.java
===================================================================
--- lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeFilter.java (revision 1690252)
+++ lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeFilter.java (working copy)
@@ -29,9 +29,9 @@
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.Filter;
import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.spatial.util.BitDocIdSetBuilder;
import org.apache.lucene.util.BitSet;
import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.DocIdSetBuilder;
/**
* Base class for Lucene Filters on SpatialPrefixTree fields.
@@ -102,10 +102,10 @@
bitSet.or(wrap(postingsEnum, acceptDocs));
}
- protected void collectDocs(BitDocIdSetBuilder bitSetBuilder) throws IOException {
+ protected void collectDocs(DocIdSetBuilder docSetBuilder) throws IOException {
assert termsEnum != null;
postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.NONE);
- bitSetBuilder.or(wrap(postingsEnum, acceptDocs));
+ docSetBuilder.add(wrap(postingsEnum, acceptDocs));
}
}
Index: lucene/spatial/src/java/org/apache/lucene/spatial/util/BitDocIdSetBuilder.java
===================================================================
--- lucene/spatial/src/java/org/apache/lucene/spatial/util/BitDocIdSetBuilder.java (revision 1690252)
+++ lucene/spatial/src/java/org/apache/lucene/spatial/util/BitDocIdSetBuilder.java (working copy)
@@ -1,119 +0,0 @@
-package org.apache.lucene.spatial.util;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 java.io.IOException;
-
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.util.BitDocIdSet;
-import org.apache.lucene.util.BitSetIterator;
-import org.apache.lucene.util.FixedBitSet;
-import org.apache.lucene.util.SparseFixedBitSet;
-
-/**
- * A builder of {@link DocIdSet}s that supports random access.
- * @lucene.internal
- */
-public final class BitDocIdSetBuilder {
-
- private final int maxDoc;
- private final int threshold;
- private SparseFixedBitSet sparseSet;
- private FixedBitSet denseSet;
-
- // we cache an upper bound of the cost of this builder so that we don't have
- // to re-compute approximateCardinality on the sparse set every time
- private long costUpperBound;
-
- /** Create a new empty instance. */
- public BitDocIdSetBuilder(int maxDoc) {
- this.maxDoc = maxDoc;
- threshold = maxDoc >>> 10;
- }
-
- // pkg-private for testing
- boolean dense() {
- return denseSet != null;
- }
-
- /**
- * Is this builder definitely empty? If so, {@link #build()} will return null. This is usually the same as
- * simply being empty but if this builder was constructed with the {@code full} option or if an iterator was passed
- * that iterated over no documents, then we're not sure.
- */
- public boolean isDefinitelyEmpty() {
- return sparseSet == null && denseSet == null;
- }
-
- /**
- * Add the content of the provided {@link DocIdSetIterator} to this builder.
- */
- public void or(DocIdSetIterator it) throws IOException {
- if (denseSet != null) {
- // already upgraded
- denseSet.or(it);
- return;
- }
-
- final long itCost = it.cost();
- costUpperBound += itCost;
- if (costUpperBound >= threshold) {
- costUpperBound = (sparseSet == null ? 0 : sparseSet.approximateCardinality()) + itCost;
-
- if (costUpperBound >= threshold) {
- // upgrade
- denseSet = new FixedBitSet(maxDoc);
- denseSet.or(it);
- if (sparseSet != null) {
- denseSet.or(new BitSetIterator(sparseSet, 0L));
- }
- return;
- }
- }
-
- // we are still sparse
- if (sparseSet == null) {
- sparseSet = new SparseFixedBitSet(maxDoc);
- }
- sparseSet.or(it);
- }
-
- /**
- * Build a {@link DocIdSet} that contains all doc ids that have been added.
- * This method may return <tt>null</tt> if no documents were addded to this
- * builder.
- * NOTE: this is a destructive operation, the builder should not be used
- * anymore after this method has been called.
- */
- public BitDocIdSet build() {
- final BitDocIdSet result;
- if (denseSet != null) {
- result = new BitDocIdSet(denseSet);
- } else if (sparseSet != null) {
- result = new BitDocIdSet(sparseSet);
- } else {
- result = null;
- }
- denseSet = null;
- sparseSet = null;
- costUpperBound = 0;
- return result;
- }
-
-}