mirror of https://github.com/apache/lucene.git
LUCENE-5529: Spatial RPT optimization to skip intersection test on redundant cells. Other small changes too.
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1578868 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7e8e19b7c0
commit
51235d2e2a
|
@ -158,6 +158,9 @@ Optimizations
|
||||||
array with length of at most equal to the specified size instead of length
|
array with length of at most equal to the specified size instead of length
|
||||||
equal to at most from + size as was before. (Martijn van Groningen)
|
equal to at most from + size as was before. (Martijn van Groningen)
|
||||||
|
|
||||||
|
* LUCENE-5529: Spatial search of non-point indexed shapes should be a little
|
||||||
|
faster due to skipping intersection tests on redundant cells. (David Smiley)
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
|
|
||||||
* LUCENE-5450: Fix getField() NPE issues with SpanOr/SpanNear when they have an
|
* LUCENE-5450: Fix getField() NPE issues with SpanOr/SpanNear when they have an
|
||||||
|
|
|
@ -17,9 +17,7 @@ package org.apache.lucene.spatial.prefix;
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.IOException;
|
import com.spatial4j.core.shape.Shape;
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
import org.apache.lucene.index.AtomicReaderContext;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
import org.apache.lucene.index.TermsEnum;
|
import org.apache.lucene.index.TermsEnum;
|
||||||
import org.apache.lucene.search.DocIdSet;
|
import org.apache.lucene.search.DocIdSet;
|
||||||
|
@ -28,7 +26,9 @@ import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
|
||||||
import org.apache.lucene.util.Bits;
|
import org.apache.lucene.util.Bits;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.lucene.util.StringHelper;
|
import org.apache.lucene.util.StringHelper;
|
||||||
import com.spatial4j.core.shape.Shape;
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Traverses a {@link SpatialPrefixTree} indexed field, using the template &
|
* Traverses a {@link SpatialPrefixTree} indexed field, using the template &
|
||||||
|
@ -60,9 +60,7 @@ public abstract class AbstractVisitingPrefixTreeFilter extends AbstractPrefixTre
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (!super.equals(o)) return false;//checks getClass == o.getClass & instanceof
|
if (!super.equals(o)) return false;//checks getClass == o.getClass & instanceof
|
||||||
|
|
||||||
AbstractVisitingPrefixTreeFilter that = (AbstractVisitingPrefixTreeFilter) o;
|
//Ignore prefixGridScanLevel as it is merely a tuning parameter.
|
||||||
|
|
||||||
if (prefixGridScanLevel != that.prefixGridScanLevel) return false;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +68,6 @@ public abstract class AbstractVisitingPrefixTreeFilter extends AbstractPrefixTre
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = super.hashCode();
|
int result = super.hashCode();
|
||||||
result = 31 * result + prefixGridScanLevel;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +87,7 @@ public abstract class AbstractVisitingPrefixTreeFilter extends AbstractPrefixTre
|
||||||
* method then it's short-circuited until it finds one, at which point
|
* method then it's short-circuited until it finds one, at which point
|
||||||
* {@link #visit(org.apache.lucene.spatial.prefix.tree.Cell)} is called. At
|
* {@link #visit(org.apache.lucene.spatial.prefix.tree.Cell)} is called. At
|
||||||
* some depths, of the tree, the algorithm switches to a scanning mode that
|
* some depths, of the tree, the algorithm switches to a scanning mode that
|
||||||
* finds calls {@link #visitScanned(org.apache.lucene.spatial.prefix.tree.Cell)}
|
* calls {@link #visitScanned(org.apache.lucene.spatial.prefix.tree.Cell)}
|
||||||
* for each leaf cell found.
|
* for each leaf cell found.
|
||||||
*
|
*
|
||||||
* @lucene.internal
|
* @lucene.internal
|
||||||
|
@ -218,7 +215,7 @@ public abstract class AbstractVisitingPrefixTreeFilter extends AbstractPrefixTre
|
||||||
if (hasIndexedLeaves && cell.getLevel() != 0) {
|
if (hasIndexedLeaves && cell.getLevel() != 0) {
|
||||||
//If the next indexed term just adds a leaf marker ('+') to cell,
|
//If the next indexed term just adds a leaf marker ('+') to cell,
|
||||||
// then add all of those docs
|
// then add all of those docs
|
||||||
assert StringHelper.startsWith(thisTerm, curVNodeTerm);
|
assert StringHelper.startsWith(thisTerm, curVNodeTerm);//TODO refactor to use method on curVNode.cell
|
||||||
scanCell = grid.getCell(thisTerm.bytes, thisTerm.offset, thisTerm.length, scanCell);
|
scanCell = grid.getCell(thisTerm.bytes, thisTerm.offset, thisTerm.length, scanCell);
|
||||||
if (scanCell.getLevel() == cell.getLevel() && scanCell.isLeaf()) {
|
if (scanCell.getLevel() == cell.getLevel() && scanCell.isLeaf()) {
|
||||||
visitLeaf(scanCell);
|
visitLeaf(scanCell);
|
||||||
|
@ -268,15 +265,17 @@ public abstract class AbstractVisitingPrefixTreeFilter extends AbstractPrefixTre
|
||||||
*/
|
*/
|
||||||
protected void scan(int scanDetailLevel) throws IOException {
|
protected void scan(int scanDetailLevel) throws IOException {
|
||||||
for (;
|
for (;
|
||||||
thisTerm != null && StringHelper.startsWith(thisTerm, curVNodeTerm);
|
thisTerm != null && StringHelper.startsWith(thisTerm, curVNodeTerm);//TODO refactor to use method on curVNode.cell
|
||||||
thisTerm = termsEnum.next()) {
|
thisTerm = termsEnum.next()) {
|
||||||
scanCell = grid.getCell(thisTerm.bytes, thisTerm.offset, thisTerm.length, scanCell);
|
scanCell = grid.getCell(thisTerm.bytes, thisTerm.offset, thisTerm.length, scanCell);
|
||||||
|
|
||||||
int termLevel = scanCell.getLevel();
|
int termLevel = scanCell.getLevel();
|
||||||
if (termLevel > scanDetailLevel)
|
if (termLevel < scanDetailLevel) {
|
||||||
continue;
|
if (scanCell.isLeaf())
|
||||||
if (termLevel == scanDetailLevel || scanCell.isLeaf()) {
|
visitScanned(scanCell);
|
||||||
visitScanned(scanCell);
|
} else if (termLevel == scanDetailLevel) {
|
||||||
|
if (!scanCell.isLeaf())//LUCENE-5529
|
||||||
|
visitScanned(scanCell);
|
||||||
}
|
}
|
||||||
}//term loop
|
}//term loop
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class TermQueryPrefixTreeStrategy extends PrefixTreeStrategy {
|
||||||
BytesRef[] terms = new BytesRef[cells.size()];
|
BytesRef[] terms = new BytesRef[cells.size()];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Cell cell : cells) {
|
for (Cell cell : cells) {
|
||||||
terms[i++] = new BytesRef(cell.getTokenString());
|
terms[i++] = new BytesRef(cell.getTokenString());//TODO use cell.getTokenBytes()
|
||||||
}
|
}
|
||||||
return new TermsFilter(getFieldName(), terms);
|
return new TermsFilter(getFieldName(), terms);
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,7 +228,7 @@ public abstract class SpatialPrefixTree {
|
||||||
assert endToken.length() == detailLevel;
|
assert endToken.length() == detailLevel;
|
||||||
List<Cell> cells = new ArrayList<>(detailLevel);
|
List<Cell> cells = new ArrayList<>(detailLevel);
|
||||||
for (int i = 1; i < detailLevel; i++) {
|
for (int i = 1; i < detailLevel; i++) {
|
||||||
cells.add(getCell(endToken.substring(0, i)));
|
cells.add(getCell(endToken.substring(0, i)));//TODO refactor: add a cell.getParent()
|
||||||
}
|
}
|
||||||
cells.add(cell);
|
cells.add(cell);
|
||||||
return cells;
|
return cells;
|
||||||
|
@ -236,6 +236,7 @@ public abstract class SpatialPrefixTree {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will add the trailing leaf byte for leaves. This isn't particularly efficient.
|
* Will add the trailing leaf byte for leaves. This isn't particularly efficient.
|
||||||
|
* @deprecated TODO remove; not used and not interesting, don't need collection in & out
|
||||||
*/
|
*/
|
||||||
public static List<String> cellsToTokenStrings(Collection<Cell> cells) {
|
public static List<String> cellsToTokenStrings(Collection<Cell> cells) {
|
||||||
List<String> tokens = new ArrayList<>((cells.size()));
|
List<String> tokens = new ArrayList<>((cells.size()));
|
||||||
|
|
Loading…
Reference in New Issue