blob: 40e48bd287c0616bf2f78173e14889b277223ef8 [file] [log] [blame]
package com.friend.find.lucene;
import java.io.IOException;
import java.util.Arrays;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.FieldCache;
import org.apache.lucene.search.Filter;
public class RangeMultiFilter extends Filter {
private String field;
private String lowerVal;
private String upperVal;
private boolean includeLower;
private boolean includeUpper;
public RangeMultiFilter(String field, String lowerVal, String upperVal, boolean includeLower, boolean includeUpper) {
this.field = field;
this.lowerVal = lowerVal;
this.upperVal = upperVal;
this.includeLower = includeLower;
this.includeUpper = includeUpper;
}
public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
// should this initialize the DMF on demand?
return new RangeMultiFilterDocIdSet(FieldCache.DEFAULT.getStringIndex(reader, field));
}
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 = Arrays.binarySearch(fcsi.lookup, lowerVal);
if (includeLower && lowerPoint >= 0) {
inclusiveLowerPoint = lowerPoint;
} else if (lowerPoint >= 0) {
inclusiveLowerPoint = lowerPoint+1;
} else {
inclusiveLowerPoint = -lowerPoint-1;
}
int upperPoint = Arrays.binarySearch(fcsi.lookup, upperVal);
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;
public int doc() {
return doc;
}
public boolean next() {
try {
do {
doc++;
} while (fcsi.order[doc] > inclusiveUpperPoint || fcsi.order[doc] < inclusiveLowerPoint);
return true;
} catch (ArrayIndexOutOfBoundsException e) {
doc = Integer.MAX_VALUE;
return false;
}
}
public boolean skipTo(int target) {
try {
doc = target;
while (fcsi.order[doc] > inclusiveUpperPoint || fcsi.order[doc] < inclusiveLowerPoint) {
doc++;
}
return true;
} catch (ArrayIndexOutOfBoundsException e) {
doc = Integer.MAX_VALUE;
return false;
}
}
}
}
}