mirror of https://github.com/apache/lucene.git
LUCENE-2669: Fix NumericRangeQuery.NumericRangeTermsEnum sometimes seeks backwards. This also adds an assert to FilteredTermsEnum that seeking only goes forward.
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1001582 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e071186aa3
commit
877e827489
|
@ -253,6 +253,11 @@ Optimizations
|
|||
interval from 128 to 32, because the terms index now requires much
|
||||
less RAM. (Robert Muir, Mike McCandless)
|
||||
|
||||
* LUCENE-2669: Optimize NumericRangeQuery.NumericRangeTermsEnum to
|
||||
not seek backwards when a sub-range has no terms. It now only seeks
|
||||
when the current term is less than the next sub-range's lower end.
|
||||
(Uwe Schindler, Mike McCandless)
|
||||
|
||||
Documentation
|
||||
|
||||
* LUCENE-2579: Fix oal.search's package.html description of abstract
|
||||
|
|
|
@ -198,6 +198,8 @@ public abstract class FilteredTermsEnum extends TermsEnum {
|
|||
if (doSeek) {
|
||||
doSeek = false;
|
||||
final BytesRef t = nextSeekTerm(actualTerm);
|
||||
// Make sure we always seek forward:
|
||||
assert actualTerm == null || t == null || getComparator().compare(t, actualTerm) > 0: "curTerm=" + actualTerm + " seekTerm=" + t;
|
||||
if (t == null || tenum.seek(t, useTermsCache) == SeekStatus.END) {
|
||||
// no more terms to seek to or enum exhausted
|
||||
return null;
|
||||
|
|
|
@ -465,28 +465,47 @@ public final class NumericRangeQuery<T extends Number> extends MultiTermQuery {
|
|||
termComp = getComparator();
|
||||
}
|
||||
|
||||
private void nextRange() {
|
||||
assert rangeBounds.size() % 2 == 0;
|
||||
|
||||
currentLowerBound = rangeBounds.removeFirst();
|
||||
assert currentUpperBound == null || termComp.compare(currentUpperBound, currentLowerBound) <= 0 :
|
||||
"The current upper bound must be <= the new lower bound";
|
||||
|
||||
currentUpperBound = rangeBounds.removeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final BytesRef nextSeekTerm(BytesRef term) throws IOException {
|
||||
if (rangeBounds.size() >= 2) {
|
||||
assert rangeBounds.size() % 2 == 0;
|
||||
|
||||
this.currentLowerBound = rangeBounds.removeFirst();
|
||||
assert currentUpperBound == null || termComp.compare(currentUpperBound, currentLowerBound) <= 0 :
|
||||
"The current upper bound must be <= the new lower bound";
|
||||
while (rangeBounds.size() >= 2) {
|
||||
nextRange();
|
||||
|
||||
this.currentUpperBound = rangeBounds.removeFirst();
|
||||
return currentLowerBound;
|
||||
// if the new upper bound is before the term parameter, the sub-range is never a hit
|
||||
if (term != null && termComp.compare(term, currentUpperBound) > 0)
|
||||
continue;
|
||||
// never seek backwards, so use current term if lower bound is smaller
|
||||
return (term != null && termComp.compare(term, currentLowerBound) > 0) ?
|
||||
term : currentLowerBound;
|
||||
}
|
||||
|
||||
// no more sub-range enums available
|
||||
assert rangeBounds.size() == 0;
|
||||
assert rangeBounds.isEmpty();
|
||||
currentLowerBound = currentUpperBound = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AcceptStatus accept(BytesRef term) {
|
||||
return (currentUpperBound != null && termComp.compare(term, currentUpperBound) <= 0) ?
|
||||
AcceptStatus.YES : AcceptStatus.NO_AND_SEEK;
|
||||
protected final AcceptStatus accept(BytesRef term) {
|
||||
while (currentUpperBound == null || termComp.compare(term, currentUpperBound) > 0) {
|
||||
if (rangeBounds.isEmpty())
|
||||
return AcceptStatus.END;
|
||||
// peek next sub-range, only seek if the current term is smaller than next lower bound
|
||||
if (termComp.compare(term, rangeBounds.getFirst()) < 0)
|
||||
return AcceptStatus.NO_AND_SEEK;
|
||||
// step forward to next range without seeking, as next lower range bound is less or equal current term
|
||||
nextRange();
|
||||
}
|
||||
return AcceptStatus.YES;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue