package org.apache.solr.request; import java.io.IOException; import org.apache.lucene.search.Query; import org.apache.solr.common.SolrException; import org.apache.solr.request.SimpleFacets.CountPair; import org.apache.solr.request.SimpleFacets.RangeEndpointCalculator; import org.apache.solr.schema.SchemaField; import org.apache.solr.search.DocSet; import org.apache.solr.search.SolrIndexSearcher; public class RangeCounter { private Comparable start; private Comparable end; private String gap; private Comparable low; private SolrIndexSearcher searcher; private DocSet base; private SchemaField sf; private RangeEndpointCalculator calc; public boolean rangeHardEnd = false; public boolean includeLower = true; public boolean includeUpper = false; public boolean includeEdge = false; public RangeCounter(RangeEndpointCalculator<?> calc, Comparable<?> start, Comparable<?> end, String gap, Comparable<?> low, SolrIndexSearcher searcher, DocSet base, SchemaField sf) { super(); this.start = start; this.end = end; this.gap = gap; this.low = low; this.searcher = searcher; this.base = base; this.calc = calc; this.sf = sf; } public CountPair<String, Integer> getNextCount() throws IOException { this.checkForCounts(); Comparable high = calc.addGap(low, gap); if (end.compareTo(high) < 0) { if (rangeHardEnd) { high = end; } else { end = high; } } if (high.compareTo(low) < 0) { throw new SolrException (SolrException.ErrorCode.BAD_REQUEST, "range facet infinite loop (is gap negative? did the math overflow?)"); } final boolean includeLower = ( this.includeLower || (this.includeEdge && 0 == low.compareTo(start)) ); final boolean includeUpper = ( this.includeUpper || (this.includeEdge && 0 == high.compareTo(end)) ); final String lowS = calc.formatValue(low); final String highS = calc.formatValue(high); final int count = rangeCount(sf, lowS, highS, includeLower,includeUpper); this.low = high; return new CountPair<String, Integer>(lowS, count); } private void checkForCounts() { if(!this.hasMoreCounts()) { throw new SolrException (SolrException.ErrorCode.BAD_REQUEST, "range counter asked for next count but has no more count to return"); } } public boolean hasMoreCounts() { return (low.compareTo(end) < 0); } private int rangeCount(SchemaField sf, String low, String high, boolean iLow, boolean iHigh) throws IOException { Query rangeQ = sf.getType().getRangeQuery(null, sf,low,high,iLow,iHigh); return searcher.numDocs(rangeQ ,base); } public Comparable getEnd() { // TODO Auto-generated method stub return this.end; } }