From d838d7bf3ad99b5a1877568273ae8c4b778a5001 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Sat, 21 Nov 2009 19:49:54 +0000 Subject: [PATCH] LUCENE-2087: Remove recursion in NumericRangeTermEnum git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@882977 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 5 +- .../lucene/search/NumericRangeQuery.java | 47 ++++++++++++------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 701fd64dd74..5e171c2e581 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -18,7 +18,10 @@ New features Optimizations * LUCENE-2086: When resolving deleted terms, do so in term sort order - for better performance (Bogdan Ghidireac via Mike McCandless) + for better performance. (Bogdan Ghidireac via Mike McCandless) + +* LUCENE-2087: Remove recursion in NumericRangeTermEnum. + (Uwe Schindler) Build diff --git a/src/java/org/apache/lucene/search/NumericRangeQuery.java b/src/java/org/apache/lucene/search/NumericRangeQuery.java index ebf9e3c4374..2c223bd9485 100644 --- a/src/java/org/apache/lucene/search/NumericRangeQuery.java +++ b/src/java/org/apache/lucene/search/NumericRangeQuery.java @@ -27,6 +27,7 @@ import org.apache.lucene.util.ToStringUtils; import org.apache.lucene.util.StringHelper; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; +import org.apache.lucene.index.TermEnum; /** *

A {@link Query} that matches numeric values within a @@ -486,6 +487,12 @@ public final class NumericRangeQuery extends MultiTermQuery { throw new UnsupportedOperationException("not implemented"); } + /** this is a dummy, it is not used by this class. */ + @Override + protected void setEnum(TermEnum tenum) { + throw new UnsupportedOperationException("not implemented"); + } + /** * Compares if current upper bound is reached, * this also updates the term count for statistics. @@ -507,29 +514,35 @@ public final class NumericRangeQuery extends MultiTermQuery { assert actualEnum != null; if (actualEnum.next()) { currentTerm = actualEnum.term(); - if (termCompare(currentTerm)) return true; + if (termCompare(currentTerm)) + return true; } } + // if all above fails, we go forward to the next enum, // if one is available currentTerm = null; - if (rangeBounds.size() < 2) { - assert rangeBounds.size() == 0; - return false; + while (rangeBounds.size() >= 2) { + assert rangeBounds.size() % 2 == 0; + // close the current enum and read next bounds + if (actualEnum != null) { + actualEnum.close(); + actualEnum = null; + } + final String lowerBound = rangeBounds.removeFirst(); + this.currentUpperBound = rangeBounds.removeFirst(); + // create a new enum + actualEnum = reader.terms(termTemplate.createTerm(lowerBound)); + currentTerm = actualEnum.term(); + if (currentTerm != null && termCompare(currentTerm)) + return true; + // clear the current term for next iteration + currentTerm = null; } - // close the current enum and read next bounds - if (actualEnum != null) { - actualEnum.close(); - actualEnum = null; - } - final String lowerBound = rangeBounds.removeFirst(); - this.currentUpperBound = rangeBounds.removeFirst(); - // this call recursively uses next(), if no valid term in - // next enum found. - // if this behavior is changed/modified in the superclass, - // this enum will not work anymore! - setEnum(reader.terms(termTemplate.createTerm(lowerBound))); - return (currentTerm != null); + + // no more sub-range enums available + assert rangeBounds.size() == 0 && currentTerm == null; + return false; } /** Closes the enumeration to further activity, freeing resources. */