Index: src/java/org/apache/lucene/search/FieldCacheRangeFilter.java =================================================================== --- src/java/org/apache/lucene/search/FieldCacheRangeFilter.java (revision 788295) +++ src/java/org/apache/lucene/search/FieldCacheRangeFilter.java (working copy) @@ -19,6 +19,7 @@ import java.io.IOException; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.util.NumericUtils; /** * A range filter built on top of a cached single term field (in FieldCache). @@ -37,56 +38,481 @@ * fields which contain zero or one terms for each document. Thus it works on dates, * prices and other single value fields but will not work on regular text fields. It is * preferable to use an UN_TOKENIZED field to ensure that there is only a single term. - * - * Also, collation is done at the time the FieldCache is built; to change - * collation you need to override the getFieldCache() method to change the underlying cache. */ -public class FieldCacheRangeFilter extends Filter { - private String field; - private String lowerVal; - private String upperVal; - private boolean includeLower; - private boolean includeUpper; +public abstract class FieldCacheRangeFilter extends Filter { + final String field; + final FieldCache.Parser parser; + final Object lowerVal; + final Object upperVal; + final boolean includeLower; + final boolean includeUpper; - public FieldCacheRangeFilter( - String field, - String lowerVal, - String upperVal, - boolean includeLower, - boolean includeUpper) { + private FieldCacheRangeFilter(String field, FieldCache.Parser parser, Object lowerVal, Object upperVal, boolean includeLower, boolean includeUpper) { + if (lowerVal == null && upperVal == null) + throw new IllegalArgumentException("At least one value must be non-null"); this.field = field; + this.parser = parser; this.lowerVal = lowerVal; this.upperVal = upperVal; this.includeLower = includeLower; this.includeUpper = includeUpper; } + + /** This method is implemented for each data type */ + abstract DocIdSetIterator newDocIdSetIterator(IndexReader reader) throws IOException; - public FieldCache getFieldCache() { - return FieldCache.DEFAULT; + public static FieldCacheRangeFilter newStringRange(String field, String lowerVal, String upperVal, boolean includeLower, boolean includeUpper) { + return new FieldCacheRangeFilter(field, null, lowerVal, upperVal, includeLower, includeUpper) { + + DocIdSetIterator newDocIdSetIterator(IndexReader reader) throws IOException { + final FieldCache.StringIndex fcsi = FieldCache.DEFAULT.getStringIndex(reader, field); + int lowerPoint = fcsi.binarySearchLookup((String) lowerVal); + int upperPoint = fcsi.binarySearchLookup((String) upperVal); + + // hint: binarySearchLookup returns 0, if value was null + + final int inclusiveLowerPoint, inclusiveUpperPoint; + if (lowerPoint == 0) { + assert lowerVal == null; + inclusiveLowerPoint = 1; + } else { + inclusiveLowerPoint = includeLower ? lowerPoint : (lowerPoint + 1); + } + if (upperPoint == 0) { + assert upperVal == null; + inclusiveUpperPoint = Integer.MAX_VALUE; + } else { + inclusiveUpperPoint = includeUpper ? upperPoint : (upperPoint - 1); + } + + if (inclusiveLowerPoint > inclusiveUpperPoint) + return DocIdSet.EMPTY_DOCIDSET.iterator(); + + return new DocIdSetIterator() { + private int doc = -1; + + public int docID() { + return doc; + } + + public int nextDoc() { + try { + do { + doc++; + } while (fcsi.order[doc] > inclusiveUpperPoint || fcsi.order[doc] < inclusiveLowerPoint); + return doc; + } catch (ArrayIndexOutOfBoundsException e) { + return NO_MORE_DOCS; + } + } + + public int advance(int target) { + try { + doc = target; + while (fcsi.order[doc] > inclusiveUpperPoint || fcsi.order[doc] < inclusiveLowerPoint) { + doc++; + } + return doc; + } catch (ArrayIndexOutOfBoundsException e) { + return NO_MORE_DOCS; + } + } + + }; + } + }; } - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { - return new RangeMultiFilterDocIdSet(getFieldCache().getStringIndex(reader, field)); + public static FieldCacheRangeFilter newByteRange(String field, Byte lowerVal, Byte upperVal, boolean includeLower, boolean includeUpper) { + return newByteRange(field, null, lowerVal, upperVal, includeLower, includeUpper); } - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append(field); - buffer.append(":"); - buffer.append(includeLower ? "[" : "{"); - if (null != lowerVal) { - buffer.append(lowerVal); - } - buffer.append("-"); - if (null != upperVal) { - buffer.append(upperVal); - } - buffer.append(includeUpper ? "]" : "}"); - return buffer.toString(); + public static FieldCacheRangeFilter newByteRange(String field, FieldCache.ByteParser parser, Byte lowerVal, Byte upperVal, boolean includeLower, boolean includeUpper) { + return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { + + DocIdSetIterator newDocIdSetIterator(IndexReader reader) throws IOException { + final byte inclusiveLowerPoint, inclusiveUpperPoint; + if (lowerVal != null) { + final byte b = ((Number) lowerVal).byteValue(); + inclusiveLowerPoint = (byte) (includeUpper ? b : (b + 1)); + } else { + inclusiveLowerPoint = Byte.MIN_VALUE; + } + if (upperVal != null) { + final byte b = ((Number) upperVal).byteValue(); + inclusiveUpperPoint = (byte) (includeUpper ? b : (b - 1)); + } else { + inclusiveUpperPoint = Byte.MAX_VALUE; + } + + if (inclusiveLowerPoint > inclusiveUpperPoint) + return DocIdSet.EMPTY_DOCIDSET.iterator(); + + final byte[] values = FieldCache.DEFAULT.getBytes(reader, field, (FieldCache.ByteParser) parser); + return new DocIdSetIterator() { + private int doc = -1; + + public int docID() { + return doc; + } + + public int nextDoc() { + try { + do { + doc++; + } while (values[doc] > inclusiveUpperPoint || values[doc] < inclusiveLowerPoint); + return doc; + } catch (ArrayIndexOutOfBoundsException e) { + return NO_MORE_DOCS; + } + } + + public int advance(int target) { + try { + doc = target; + while (values[doc] > inclusiveUpperPoint || values[doc] < inclusiveLowerPoint) { + doc++; + } + return doc; + } catch (ArrayIndexOutOfBoundsException e) { + return NO_MORE_DOCS; + } + } + + }; + } + }; } + + public static FieldCacheRangeFilter newShortRange(String field, Short lowerVal, Short upperVal, boolean includeLower, boolean includeUpper) { + return newShortRange(field, null, lowerVal, upperVal, includeLower, includeUpper); + } + + public static FieldCacheRangeFilter newShortRange(String field, FieldCache.ShortParser parser, Short lowerVal, Short upperVal, boolean includeLower, boolean includeUpper) { + return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { + + DocIdSetIterator newDocIdSetIterator(IndexReader reader) throws IOException { + final short inclusiveLowerPoint, inclusiveUpperPoint; + if (lowerVal != null) { + short i = ((Number) lowerVal).shortValue(); + inclusiveLowerPoint = (short) (includeUpper ? i : (i + 1)); + } else { + inclusiveLowerPoint = Short.MIN_VALUE; + } + if (upperVal != null) { + short i = ((Number) upperVal).shortValue(); + inclusiveUpperPoint = (short) (includeUpper ? i : (i - 1)); + } else { + inclusiveUpperPoint = Short.MAX_VALUE; + } + + if (inclusiveLowerPoint > inclusiveUpperPoint) + return DocIdSet.EMPTY_DOCIDSET.iterator(); + + final short[] values = FieldCache.DEFAULT.getShorts(reader, field, (FieldCache.ShortParser) parser); + return new DocIdSetIterator() { + private int doc = -1; - public boolean equals(Object o) { + public int docID() { + return doc; + } + + public int nextDoc() { + try { + do { + doc++; + } while (values[doc] > inclusiveUpperPoint || values[doc] < inclusiveLowerPoint); + return doc; + } catch (ArrayIndexOutOfBoundsException e) { + return NO_MORE_DOCS; + } + } + + public int advance(int target) { + try { + doc = target; + while (values[doc] > inclusiveUpperPoint || values[doc] < inclusiveLowerPoint) { + doc++; + } + return doc; + } catch (ArrayIndexOutOfBoundsException e) { + return NO_MORE_DOCS; + } + } + + }; + } + }; + } + + public static FieldCacheRangeFilter newIntRange(String field, Integer lowerVal, Integer upperVal, boolean includeLower, boolean includeUpper) { + return newIntRange(field, null, lowerVal, upperVal, includeLower, includeUpper); + } + + public static FieldCacheRangeFilter newIntRange(String field, FieldCache.IntParser parser, Integer lowerVal, Integer upperVal, boolean includeLower, boolean includeUpper) { + return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { + + DocIdSetIterator newDocIdSetIterator(IndexReader reader) throws IOException { + final int inclusiveLowerPoint, inclusiveUpperPoint; + if (lowerVal != null) { + int i = ((Number) lowerVal).intValue(); + inclusiveLowerPoint = includeUpper ? i : (i + 1); + } else { + inclusiveLowerPoint = Integer.MIN_VALUE; + } + if (upperVal != null) { + int i = ((Number) upperVal).intValue(); + inclusiveUpperPoint = includeUpper ? i : (i - 1); + } else { + inclusiveUpperPoint = Integer.MAX_VALUE; + } + + if (inclusiveLowerPoint > inclusiveUpperPoint) + return DocIdSet.EMPTY_DOCIDSET.iterator(); + + final int[] values = FieldCache.DEFAULT.getInts(reader, field, (FieldCache.IntParser) parser); + return new DocIdSetIterator() { + private int doc = -1; + + public int docID() { + return doc; + } + + public int nextDoc() { + try { + do { + doc++; + } while (values[doc] > inclusiveUpperPoint || values[doc] < inclusiveLowerPoint); + return doc; + } catch (ArrayIndexOutOfBoundsException e) { + return NO_MORE_DOCS; + } + } + + public int advance(int target) { + try { + doc = target; + while (values[doc] > inclusiveUpperPoint || values[doc] < inclusiveLowerPoint) { + doc++; + } + return doc; + } catch (ArrayIndexOutOfBoundsException e) { + return NO_MORE_DOCS; + } + } + + }; + } + }; + } + + public static FieldCacheRangeFilter newLongRange(String field, Long lowerVal, Long upperVal, boolean includeLower, boolean includeUpper) { + return newLongRange(field, null, lowerVal, upperVal, includeLower, includeUpper); + } + + public static FieldCacheRangeFilter newLongRange(String field, FieldCache.LongParser parser, Long lowerVal, Long upperVal, boolean includeLower, boolean includeUpper) { + return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { + + DocIdSetIterator newDocIdSetIterator(IndexReader reader) throws IOException { + final long inclusiveLowerPoint, inclusiveUpperPoint; + if (lowerVal != null) { + long i = ((Number) lowerVal).longValue(); + inclusiveLowerPoint = includeUpper ? i : (i + 1L); + } else { + inclusiveLowerPoint = Long.MIN_VALUE; + } + if (upperVal != null) { + long i = ((Number) upperVal).longValue(); + inclusiveUpperPoint = includeUpper ? i : (i - 1L); + } else { + inclusiveUpperPoint = Long.MAX_VALUE; + } + + if (inclusiveLowerPoint > inclusiveUpperPoint) + return DocIdSet.EMPTY_DOCIDSET.iterator(); + + final long[] values = FieldCache.DEFAULT.getLongs(reader, field, (FieldCache.LongParser) parser); + return new DocIdSetIterator() { + private int doc = -1; + + public int docID() { + return doc; + } + + public int nextDoc() { + try { + do { + doc++; + } while (values[doc] > inclusiveUpperPoint || values[doc] < inclusiveLowerPoint); + return doc; + } catch (ArrayIndexOutOfBoundsException e) { + return NO_MORE_DOCS; + } + } + + public int advance(int target) { + try { + doc = target; + while (values[doc] > inclusiveUpperPoint || values[doc] < inclusiveLowerPoint) { + doc++; + } + return doc; + } catch (ArrayIndexOutOfBoundsException e) { + return NO_MORE_DOCS; + } + } + + }; + } + }; + } + + public static FieldCacheRangeFilter newFloatRange(String field, Float lowerVal, Float upperVal, boolean includeLower, boolean includeUpper) { + return newFloatRange(field, null, lowerVal, upperVal, includeLower, includeUpper); + } + + public static FieldCacheRangeFilter newFloatRange(String field, FieldCache.FloatParser parser, Float lowerVal, Float upperVal, boolean includeLower, boolean includeUpper) { + return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { + + DocIdSetIterator newDocIdSetIterator(IndexReader reader) throws IOException { + // we transform the floating point numbers to sortable integers + // using NumericUtils to easier find the next bigger/lower value + final float inclusiveLowerPoint, inclusiveUpperPoint; + if (lowerVal != null) { + int i = NumericUtils.floatToSortableInt(((Number) lowerVal).floatValue()); + inclusiveLowerPoint = NumericUtils.sortableIntToFloat( includeUpper ? i : (i + 1) ); + } else { + inclusiveLowerPoint = Float.NEGATIVE_INFINITY; + } + if (upperVal != null) { + int i = NumericUtils.floatToSortableInt(((Number) upperVal).floatValue()); + inclusiveUpperPoint = NumericUtils.sortableIntToFloat( includeUpper ? i : (i - 1) ); + } else { + inclusiveUpperPoint = Float.POSITIVE_INFINITY; + } + + if (inclusiveLowerPoint > inclusiveUpperPoint) + return DocIdSet.EMPTY_DOCIDSET.iterator(); + + final float[] values = FieldCache.DEFAULT.getFloats(reader, field, (FieldCache.FloatParser) parser); + return new DocIdSetIterator() { + private int doc = -1; + + public int docID() { + return doc; + } + + public int nextDoc() { + try { + do { + doc++; + } while (values[doc] > inclusiveUpperPoint || values[doc] < inclusiveLowerPoint); + return doc; + } catch (ArrayIndexOutOfBoundsException e) { + return NO_MORE_DOCS; + } + } + + public int advance(int target) { + try { + doc = target; + while (values[doc] > inclusiveUpperPoint || values[doc] < inclusiveLowerPoint) { + doc++; + } + return doc; + } catch (ArrayIndexOutOfBoundsException e) { + return NO_MORE_DOCS; + } + } + + }; + } + }; + } + + public static FieldCacheRangeFilter newDoubleRange(String field, Double lowerVal, Double upperVal, boolean includeLower, boolean includeUpper) { + return newDoubleRange(field, null, lowerVal, upperVal, includeLower, includeUpper); + } + + public static FieldCacheRangeFilter newDoubleRange(String field, FieldCache.DoubleParser parser, Double lowerVal, Double upperVal, boolean includeLower, boolean includeUpper) { + return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { + + DocIdSetIterator newDocIdSetIterator(IndexReader reader) throws IOException { + // we transform the floating point numbers to sortable integers + // using NumericUtils to easier find the next bigger/lower value + final double inclusiveLowerPoint, inclusiveUpperPoint; + if (lowerVal != null) { + long i = NumericUtils.doubleToSortableLong(((Number) lowerVal).doubleValue()); + inclusiveLowerPoint = NumericUtils.sortableLongToDouble( includeUpper ? i : (i + 1L) ); + } else { + inclusiveLowerPoint = Double.NEGATIVE_INFINITY; + } + if (upperVal != null) { + long i = NumericUtils.doubleToSortableLong(((Number) upperVal).doubleValue()); + inclusiveUpperPoint = NumericUtils.sortableLongToDouble( includeUpper ? i : (i - 1L) ); + } else { + inclusiveUpperPoint = Double.POSITIVE_INFINITY; + } + + if (inclusiveLowerPoint > inclusiveUpperPoint) + return DocIdSet.EMPTY_DOCIDSET.iterator(); + + final double[] values = FieldCache.DEFAULT.getDoubles(reader, field, (FieldCache.DoubleParser) parser); + return new DocIdSetIterator() { + private int doc = -1; + + public int docID() { + return doc; + } + + public int nextDoc() { + try { + do { + doc++; + } while (values[doc] > inclusiveUpperPoint || values[doc] < inclusiveLowerPoint); + return doc; + } catch (ArrayIndexOutOfBoundsException e) { + return NO_MORE_DOCS; + } + } + + public int advance(int target) { + try { + doc = target; + while (values[doc] > inclusiveUpperPoint || values[doc] < inclusiveLowerPoint) { + doc++; + } + return doc; + } catch (ArrayIndexOutOfBoundsException e) { + return NO_MORE_DOCS; + } + } + + }; + } + }; + } + + public final DocIdSet getDocIdSet(final IndexReader reader) throws IOException { + return new DocIdSet() { + public DocIdSetIterator iterator() throws IOException { + return newDocIdSetIterator(reader); + } + }; + } + + public final String toString() { + final StringBuffer sb = new StringBuffer(field).append(":"); + return sb.append(includeLower ? '[' : '{') + .append((lowerVal == null) ? "*" : lowerVal.toString()) + .append(" TO ") + .append((upperVal == null) ? "*" : upperVal.toString()) + .append(includeUpper ? ']' : '}') + .toString(); + } + + public final boolean equals(Object o) { if (this == o) return true; if (!(o instanceof FieldCacheRangeFilter)) return false; FieldCacheRangeFilter other = (FieldCacheRangeFilter) o; @@ -97,112 +523,18 @@ ) { return false; } if (this.lowerVal != null ? !this.lowerVal.equals(other.lowerVal) : other.lowerVal != null) return false; if (this.upperVal != null ? !this.upperVal.equals(other.upperVal) : other.upperVal != null) return false; + if (this.parser != null ? !this.parser.equals(other.parser) : other.parser != null) return false; return true; } - public int hashCode() { + public final int hashCode() { int h = field.hashCode(); - h ^= lowerVal != null ? lowerVal.hashCode() : 550356204; + h ^= (lowerVal != null) ? lowerVal.hashCode() : 550356204; h = (h << 1) | (h >>> 31); // rotate to distinguish lower from upper - h ^= (upperVal != null ? (upperVal.hashCode()) : -1674416163); - h ^= (includeLower ? 1549299360 : -365038026) - ^ (includeUpper ? 1721088258 : 1948649653); - + h ^= (upperVal != null) ? upperVal.hashCode() : -1674416163; + h ^= (parser != null) ? parser.hashCode() : -1572457324; + h ^= (includeLower ? 1549299360 : -365038026) ^ (includeUpper ? 1721088258 : 1948649653); return h; } - protected class RangeMultiFilterDocIdSet extends DocIdSet { - private int inclusiveLowerPoint; - private int inclusiveUpperPoint; - private FieldCache.StringIndex fcsi; - - public RangeMultiFilterDocIdSet(FieldCache.StringIndex fcsi) { - this.fcsi = fcsi; - initialize(); - } - - private void initialize() { - int lowerPoint = fcsi.binarySearchLookup(lowerVal); - int upperPoint = fcsi.binarySearchLookup(upperVal); - - if (lowerPoint == 0 && upperPoint == 0) { - throw new IllegalArgumentException("At least one value must be non-null"); - } - - if (includeLower && lowerPoint == 0) { - throw new IllegalArgumentException("The lower bound must be non-null to be inclusive"); - } else if (includeLower && lowerPoint > 0) { - inclusiveLowerPoint = lowerPoint; - } else if (lowerPoint >= 0) { - inclusiveLowerPoint = lowerPoint+1; - } else { - inclusiveLowerPoint = -lowerPoint-1; - } - - if (includeUpper && upperPoint == 0) { - throw new IllegalArgumentException("The upper bound must be non-null to be inclusive"); - } else if (upperPoint == 0) { - inclusiveUpperPoint = Integer.MAX_VALUE; - } else if (includeUpper && upperPoint > 0) { - inclusiveUpperPoint = upperPoint; - } else if (upperPoint >= 0) { - inclusiveUpperPoint = upperPoint - 1; - } else { - inclusiveUpperPoint = -upperPoint - 2; - } - } - - public DocIdSetIterator iterator() { - return new RangeMultiFilterIterator(); - } - - protected class RangeMultiFilterIterator extends DocIdSetIterator { - private int doc = -1; - - /** @deprecated use {@link #docID()} instead. */ - public int doc() { - return doc; - } - - public int docID() { - return doc; - } - - /** @deprecated use {@link #nextDoc()} instead. */ - public boolean next() { - return nextDoc() != NO_MORE_DOCS; - } - - public int nextDoc() { - try { - do { - doc++; - } while (fcsi.order[doc] > inclusiveUpperPoint - || fcsi.order[doc] < inclusiveLowerPoint); - } catch (ArrayIndexOutOfBoundsException e) { - doc = NO_MORE_DOCS; - } - return doc; - } - - /** @deprecated use {@link #advance(int)} instead. */ - public boolean skipTo(int target) { - return advance(target) != NO_MORE_DOCS; - } - - public int advance(int target) { - try { - doc = target; - while (fcsi.order[doc] > inclusiveUpperPoint - || fcsi.order[doc] < inclusiveLowerPoint) { - doc++; - } - } catch (ArrayIndexOutOfBoundsException e) { - doc = NO_MORE_DOCS; - } - return doc; - } - - } - } } Index: src/test/org/apache/lucene/search/TestFieldCacheRangeFilter.java =================================================================== --- src/test/org/apache/lucene/search/TestFieldCacheRangeFilter.java (revision 788295) +++ src/test/org/apache/lucene/search/TestFieldCacheRangeFilter.java (working copy) @@ -67,64 +67,64 @@ // test id, bounded on both ends - result = search.search(q,new FieldCacheRangeFilter("id",minIP,maxIP,T,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",minIP,maxIP,T,T), numDocs).scoreDocs; assertEquals("find all", numDocs, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",minIP,maxIP,T,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",minIP,maxIP,T,F), numDocs).scoreDocs; assertEquals("all but last", numDocs-1, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",minIP,maxIP,F,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",minIP,maxIP,F,T), numDocs).scoreDocs; assertEquals("all but first", numDocs-1, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",minIP,maxIP,F,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",minIP,maxIP,F,F), numDocs).scoreDocs; assertEquals("all but ends", numDocs-2, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",medIP,maxIP,T,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",medIP,maxIP,T,T), numDocs).scoreDocs; assertEquals("med and up", 1+ maxId-medId, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",minIP,medIP,T,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",minIP,medIP,T,T), numDocs).scoreDocs; assertEquals("up to med", 1+ medId-minId, result.length); // unbounded id - result = search.search(q,new FieldCacheRangeFilter("id",minIP,null,T,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",minIP,null,T,F), numDocs).scoreDocs; assertEquals("min and up", numDocs, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",null,maxIP,F,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",null,maxIP,F,T), numDocs).scoreDocs; assertEquals("max and down", numDocs, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",minIP,null,F,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",minIP,null,F,F), numDocs).scoreDocs; assertEquals("not min, but up", numDocs-1, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",null,maxIP,F,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",null,maxIP,F,F), numDocs).scoreDocs; assertEquals("not max, but down", numDocs-1, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",medIP,maxIP,T,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",medIP,maxIP,T,F), numDocs).scoreDocs; assertEquals("med and up, not max", maxId-medId, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",minIP,medIP,F,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",minIP,medIP,F,T), numDocs).scoreDocs; assertEquals("not min, up to med", medId-minId, result.length); // very small sets - result = search.search(q,new FieldCacheRangeFilter("id",minIP,minIP,F,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",minIP,minIP,F,F), numDocs).scoreDocs; assertEquals("min,min,F,F", 0, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",medIP,medIP,F,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",medIP,medIP,F,F), numDocs).scoreDocs; assertEquals("med,med,F,F", 0, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",maxIP,maxIP,F,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",maxIP,maxIP,F,F), numDocs).scoreDocs; assertEquals("max,max,F,F", 0, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",minIP,minIP,T,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",minIP,minIP,T,T), numDocs).scoreDocs; assertEquals("min,min,T,T", 1, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",null,minIP,F,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",null,minIP,F,T), numDocs).scoreDocs; assertEquals("nul,min,F,T", 1, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",maxIP,maxIP,T,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",maxIP,maxIP,T,T), numDocs).scoreDocs; assertEquals("max,max,T,T", 1, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",maxIP,null,T,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",maxIP,null,T,F), numDocs).scoreDocs; assertEquals("max,nul,T,T", 1, result.length); - result = search.search(q,new FieldCacheRangeFilter("id",medIP,medIP,T,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("id",medIP,medIP,T,T), numDocs).scoreDocs; assertEquals("med,med,T,T", 1, result.length); } @@ -146,47 +146,47 @@ // test extremes, bounded on both ends - result = search.search(q,new FieldCacheRangeFilter("rand",minRP,maxRP,T,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("rand",minRP,maxRP,T,T), numDocs).scoreDocs; assertEquals("find all", numDocs, result.length); - result = search.search(q,new FieldCacheRangeFilter("rand",minRP,maxRP,T,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("rand",minRP,maxRP,T,F), numDocs).scoreDocs; assertEquals("all but biggest", numDocs-1, result.length); - result = search.search(q,new FieldCacheRangeFilter("rand",minRP,maxRP,F,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("rand",minRP,maxRP,F,T), numDocs).scoreDocs; assertEquals("all but smallest", numDocs-1, result.length); - result = search.search(q,new FieldCacheRangeFilter("rand",minRP,maxRP,F,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("rand",minRP,maxRP,F,F), numDocs).scoreDocs; assertEquals("all but extremes", numDocs-2, result.length); // unbounded - result = search.search(q,new FieldCacheRangeFilter("rand",minRP,null,T,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("rand",minRP,null,T,F), numDocs).scoreDocs; assertEquals("smallest and up", numDocs, result.length); - result = search.search(q,new FieldCacheRangeFilter("rand",null,maxRP,F,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("rand",null,maxRP,F,T), numDocs).scoreDocs; assertEquals("biggest and down", numDocs, result.length); - result = search.search(q,new FieldCacheRangeFilter("rand",minRP,null,F,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("rand",minRP,null,F,F), numDocs).scoreDocs; assertEquals("not smallest, but up", numDocs-1, result.length); - result = search.search(q,new FieldCacheRangeFilter("rand",null,maxRP,F,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("rand",null,maxRP,F,F), numDocs).scoreDocs; assertEquals("not biggest, but down", numDocs-1, result.length); // very small sets - result = search.search(q,new FieldCacheRangeFilter("rand",minRP,minRP,F,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("rand",minRP,minRP,F,F), numDocs).scoreDocs; assertEquals("min,min,F,F", 0, result.length); - result = search.search(q,new FieldCacheRangeFilter("rand",maxRP,maxRP,F,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("rand",maxRP,maxRP,F,F), numDocs).scoreDocs; assertEquals("max,max,F,F", 0, result.length); - result = search.search(q,new FieldCacheRangeFilter("rand",minRP,minRP,T,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("rand",minRP,minRP,T,T), numDocs).scoreDocs; assertEquals("min,min,T,T", 1, result.length); - result = search.search(q,new FieldCacheRangeFilter("rand",null,minRP,F,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("rand",null,minRP,F,T), numDocs).scoreDocs; assertEquals("nul,min,F,T", 1, result.length); - result = search.search(q,new FieldCacheRangeFilter("rand",maxRP,maxRP,T,T), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("rand",maxRP,maxRP,T,T), numDocs).scoreDocs; assertEquals("max,max,T,T", 1, result.length); - result = search.search(q,new FieldCacheRangeFilter("rand",maxRP,null,T,F), numDocs).scoreDocs; + result = search.search(q,FieldCacheRangeFilter.newStringRange("rand",maxRP,null,T,F), numDocs).scoreDocs; assertEquals("max,nul,T,T", 1, result.length); } } Index: src/test/org/apache/lucene/search/TestNumericRangeQuery32.java =================================================================== --- src/test/org/apache/lucene/search/TestNumericRangeQuery32.java (revision 788295) +++ src/test/org/apache/lucene/search/TestNumericRangeQuery32.java (working copy) @@ -220,38 +220,50 @@ } // test inclusive range NumericRangeQuery tq=NumericRangeQuery.newIntRange(field, precisionStep, new Integer(lower), new Integer(upper), true, true); + FieldCacheRangeFilter fcr=FieldCacheRangeFilter.newIntRange(field, new Integer(lower), new Integer(upper), true, true); RangeQuery cq=new RangeQuery(field, NumericUtils.intToPrefixCoded(lower), NumericUtils.intToPrefixCoded(upper), true, true); cq.setConstantScoreRewrite(true); TopDocs tTopDocs = searcher.search(tq, 1); TopDocs cTopDocs = searcher.search(cq, 1); + TopDocs fTopDocs = searcher.search(new ConstantScoreQuery(fcr), 1); assertEquals("Returned count for NumericRangeQuery and RangeQuery must be equal", cTopDocs.totalHits, tTopDocs.totalHits ); + assertEquals("Returned count for NumericRangeQuery and FieldCacheRangeFilter must be equal", fTopDocs.totalHits, tTopDocs.totalHits ); termCountT += tq.getTotalNumberOfTerms(); termCountC += cq.getTotalNumberOfTerms(); // test exclusive range tq=NumericRangeQuery.newIntRange(field, precisionStep, new Integer(lower), new Integer(upper), false, false); + fcr=FieldCacheRangeFilter.newIntRange(field, new Integer(lower), new Integer(upper), false, false); cq=new RangeQuery(field, NumericUtils.intToPrefixCoded(lower), NumericUtils.intToPrefixCoded(upper), false, false); cq.setConstantScoreRewrite(true); tTopDocs = searcher.search(tq, 1); cTopDocs = searcher.search(cq, 1); + fTopDocs = searcher.search(new ConstantScoreQuery(fcr), 1); assertEquals("Returned count for NumericRangeQuery and RangeQuery must be equal", cTopDocs.totalHits, tTopDocs.totalHits ); + assertEquals("Returned count for NumericRangeQuery and FieldCacheRangeFilter must be equal", fTopDocs.totalHits, tTopDocs.totalHits ); termCountT += tq.getTotalNumberOfTerms(); termCountC += cq.getTotalNumberOfTerms(); // test left exclusive range tq=NumericRangeQuery.newIntRange(field, precisionStep, new Integer(lower), new Integer(upper), false, true); + fcr=FieldCacheRangeFilter.newIntRange(field, new Integer(lower), new Integer(upper), false, true); cq=new RangeQuery(field, NumericUtils.intToPrefixCoded(lower), NumericUtils.intToPrefixCoded(upper), false, true); cq.setConstantScoreRewrite(true); tTopDocs = searcher.search(tq, 1); cTopDocs = searcher.search(cq, 1); + fTopDocs = searcher.search(new ConstantScoreQuery(fcr), 1); assertEquals("Returned count for NumericRangeQuery and RangeQuery must be equal", cTopDocs.totalHits, tTopDocs.totalHits ); + assertEquals("Returned count for NumericRangeQuery and FieldCacheRangeFilter must be equal", fTopDocs.totalHits, tTopDocs.totalHits ); termCountT += tq.getTotalNumberOfTerms(); termCountC += cq.getTotalNumberOfTerms(); // test right exclusive range tq=NumericRangeQuery.newIntRange(field, precisionStep, new Integer(lower), new Integer(upper), true, false); + fcr=FieldCacheRangeFilter.newIntRange(field, new Integer(lower), new Integer(upper), true, false); cq=new RangeQuery(field, NumericUtils.intToPrefixCoded(lower), NumericUtils.intToPrefixCoded(upper), true, false); cq.setConstantScoreRewrite(true); tTopDocs = searcher.search(tq, 1); cTopDocs = searcher.search(cq, 1); + fTopDocs = searcher.search(new ConstantScoreQuery(fcr), 1); assertEquals("Returned count for NumericRangeQuery and RangeQuery must be equal", cTopDocs.totalHits, tTopDocs.totalHits ); + assertEquals("Returned count for NumericRangeQuery and FieldCacheRangeFilter must be equal", fTopDocs.totalHits, tTopDocs.totalHits ); termCountT += tq.getTotalNumberOfTerms(); termCountC += cq.getTotalNumberOfTerms(); }