mirror of https://github.com/apache/lucene.git
LUCENE-5648: (NumberRangePrefixTree) Bug-fix in initIter optimization. Re-index required.
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1602857 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
dc8e53b11a
commit
0a70e721ce
|
@ -96,17 +96,29 @@ public abstract class NumberRangePrefixTree extends SpatialPrefixTree {
|
|||
protected class NRShape implements Shape {
|
||||
|
||||
private final LevelledValue minLV, maxLV;
|
||||
private final int lastLevelInCommon;//computed; not part of identity
|
||||
|
||||
/** Don't call directly; see {@link #toRangeShape(com.spatial4j.core.shape.Shape, com.spatial4j.core.shape.Shape)}. */
|
||||
private NRShape(LevelledValue minLV, LevelledValue maxLV) {
|
||||
this.minLV = minLV;
|
||||
this.maxLV = maxLV;
|
||||
|
||||
//calc lastLevelInCommon
|
||||
int level = 1;
|
||||
for (; level <= minLV.getLevel() && level <= maxLV.getLevel(); level++) {
|
||||
if (minLV.getValAtLevel(level) != maxLV.getValAtLevel(level))
|
||||
break;
|
||||
}
|
||||
lastLevelInCommon = level - 1;
|
||||
}
|
||||
|
||||
public LevelledValue getMinLV() { return minLV; }
|
||||
|
||||
public LevelledValue getMaxLV() { return maxLV; }
|
||||
|
||||
/** How many levels are in common between minLV and maxLV. */
|
||||
private int getLastLevelInCommon() { return lastLevelInCommon; }
|
||||
|
||||
@Override
|
||||
public SpatialRelation relate(Shape shape) {
|
||||
// if (shape instanceof LevelledValue)
|
||||
|
@ -561,11 +573,11 @@ public abstract class NumberRangePrefixTree extends SpatialPrefixTree {
|
|||
|
||||
private void initIter(Shape filter) {
|
||||
cellNumber = -1;
|
||||
if (filter instanceof LevelledValue && ((LevelledValue)filter).getLevel() == 0)
|
||||
if (filter instanceof LevelledValue && ((LevelledValue) filter).getLevel() == 0)
|
||||
filter = null;//world means everything -- no filter
|
||||
iterFilter = filter;
|
||||
|
||||
NRCell parent = getLVAtLevel(getLevel()-1);
|
||||
NRCell parent = getLVAtLevel(getLevel() - 1);
|
||||
|
||||
// Initialize iter* members.
|
||||
|
||||
|
@ -580,17 +592,22 @@ public abstract class NumberRangePrefixTree extends SpatialPrefixTree {
|
|||
|
||||
final LevelledValue minLV;
|
||||
final LevelledValue maxLV;
|
||||
final int lastLevelInCommon;//between minLV & maxLV
|
||||
if (filter instanceof NRShape) {
|
||||
NRShape nrShape = (NRShape) iterFilter;
|
||||
minLV = nrShape.getMinLV();
|
||||
maxLV = nrShape.getMaxLV();
|
||||
lastLevelInCommon = nrShape.getLastLevelInCommon();
|
||||
} else {
|
||||
minLV = (LevelledValue)iterFilter;
|
||||
minLV = (LevelledValue) iterFilter;
|
||||
maxLV = minLV;
|
||||
lastLevelInCommon = minLV.getLevel();
|
||||
}
|
||||
|
||||
//fast path check when using same filter
|
||||
if (iterFilter == parent.iterFilter) {
|
||||
//fast path optimization that is usually true, but never first level
|
||||
if (iterFilter == parent.iterFilter &&
|
||||
(getLevel() <= lastLevelInCommon || parent.iterFirstCellNumber != parent.iterLastCellNumber)) {
|
||||
//TODO benchmark if this optimization pays off. We avoid two comparePrefixLV calls.
|
||||
if (parent.iterFirstIsIntersects && parent.cellNumber == parent.iterFirstCellNumber
|
||||
&& minLV.getLevel() >= getLevel()) {
|
||||
iterFirstCellNumber = minLV.getValAtLevel(getLevel());
|
||||
|
@ -616,7 +633,7 @@ public abstract class NumberRangePrefixTree extends SpatialPrefixTree {
|
|||
return;
|
||||
}
|
||||
|
||||
//uncommon to get here, except for level 1 which always happens
|
||||
//not common to get here, except for level 1 which always happens
|
||||
|
||||
int startCmp = comparePrefixLV(minLV, parent);
|
||||
if (startCmp > 0) {//start comes after this cell
|
||||
|
@ -650,6 +667,12 @@ public abstract class NumberRangePrefixTree extends SpatialPrefixTree {
|
|||
iterLastCellNumber = maxLV.getValAtLevel(getLevel());
|
||||
iterLastIsIntersects = (maxLV.getLevel() > getLevel());
|
||||
}
|
||||
if (iterFirstCellNumber == iterLastCellNumber) {
|
||||
if (iterLastIsIntersects)
|
||||
iterFirstIsIntersects = true;
|
||||
else if (iterFirstIsIntersects)
|
||||
iterLastIsIntersects = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -91,6 +91,15 @@ public class DateNRStrategyTest extends BaseNonFuzzySpatialOpStrategyTest {
|
|||
tree.toShape(randomCalendar()), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBugInitIterOptimization() throws Exception {
|
||||
//bug due to fast path initIter() optimization
|
||||
testOperation(
|
||||
tree.parseShape("[2014-03-27T23 TO 2014-04-01T01]"),
|
||||
SpatialOperation.Intersects,
|
||||
tree.parseShape("[2014-04 TO 2014-04-01T02]"), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Shape randomIndexedShape() {
|
||||
Calendar cal1 = randomCalendar();
|
||||
|
|
Loading…
Reference in New Issue