content: package org.apache.solr.request.uninverted;
  
  import java.io.IOException;
  import org.apache.lucene.index.IndexReader;
  import org.apache.lucene.index.Term;
  import org.apache.lucene.index.TermDocs;
  import org.apache.lucene.index.TermEnum;
  
  public  class TermNumEnumerator extends TermEnum {
  //	  public static Logger log = LoggerFactory.getLogger(TermNumEnumerator.class);
  
  	  protected final IndexReader reader;
  	  protected final TermIndex tindex;
  	  protected TermEnum tenum;
  	  protected int pos=-1;
  	  protected Term t;
  	  protected TermDocs termDocs;
  
  
  	  TermNumEnumerator(IndexReader reader, TermIndex tindex) throws IOException {
  	    this.reader = reader;
  	    this.tindex = tindex;
  	  }
  
  
  	  TermNumEnumerator(IndexReader reader, TermIndex tindex, String termValue, int pos) throws IOException {
  	    this.reader = reader;
  	    this.tindex = tindex;
  	    this.pos = pos;
  	    tenum = reader.terms(tindex.createTerm(termValue));
  	    setTerm();
  	  }
  
  	  public TermDocs getTermDocs() throws IOException {
  	    if (termDocs==null) termDocs = reader.termDocs(t,102400);
  	    else termDocs.seek(t);
  	    return termDocs;
  	  }
  
  	  protected boolean setTerm() {
  	    t = tenum.term();
  	    if (t==null
  	            || t.field() != tindex.fterm.field()  // intern'd compare
  	            || (tindex.prefix != null && !t.text().startsWith(tindex.prefix,0)) )
  	    {
  	      t = null;
  	      return false;
  	    }
  	    return true;
  	  }
  
  
  	  @Override
  	  public boolean next() throws IOException {
  	    pos++;
  	    boolean b = tenum.next();
  	    if (!b) {
  	      t = null;
  	      return false;
  	    }
  	    return setTerm();  // this is extra work if we know we are in bounds...
  	  }
  
  	  @Override
  	  public Term term() {
  	    return t;
  	  }
  
  	  @Override
  	  public int docFreq() {
  	    return tenum.docFreq();
  	  }
  
  	  @Override
  	  public void close() throws IOException {
  	    if (tenum!=null) tenum.close();
  	  }
  
  	  public boolean skipTo(String target) throws IOException {
  	    return skipTo(tindex.fterm.createTerm(target));
  	  }
  
  	  public boolean skipTo(Term target) throws IOException {
  	    // already here
  	    if (t != null && t.equals(target)) return true;
  
  	    int startIdx = tindex.index.search(target.text());
  
  	    if (startIdx >= 0) {
  	      // we hit the term exactly... lucky us!
  	      if (tenum != null) tenum.close();
  	      tenum = reader.terms(target);
  	      pos = startIdx << tindex.intervalBits;
  	      return setTerm();
  	    }
  
  	    // we didn't hit the term exactly
  	    startIdx=-startIdx-1;
  
  	    if (startIdx == 0) {
  	      // our target occurs *before* the first term
  	      if (tenum != null) tenum.close();
  	      tenum = reader.terms(target);
  	      pos = 0;
  	      return setTerm();
  	    }
  
  	    // back up to the start of the block
  	    startIdx--;
  
  	    if ((pos >> tindex.intervalBits) == startIdx && t != null && t.text().compareTo(target.text())<=0) {
  	      // we are already in the right block and the current term is before the term we want,
  	      // so we don't need to seek.
  	    } else {
  	      // seek to the right block
  	      if (tenum != null) tenum.close();            
  	      tenum = reader.terms(target.createTerm(tindex.index.get(startIdx)));
  	      pos = startIdx << tindex.intervalBits;
  	      setTerm();  // should be true since it's in the index
  	    }
  
  
  	    while (t != null && t.text().compareTo(target.text()) < 0) {
  	      next();
  	    }
  
  	    return t != null;
  	  }
  
  
  	  public boolean skipTo(int termNumber) throws IOException {
  	    int delta = termNumber - pos;
  	    if (delta < 0 || delta > tindex.interval || tenum==null) {
  	      int idx = termNumber >>> tindex.intervalBits;
  	      String base = tindex.index.get(idx);
  	      pos = idx << tindex.intervalBits;
  	      delta = termNumber - pos;
  	      if (tenum != null) {tenum.close();}
  	      tenum = reader.terms(tindex.createTerm(base));
  	    }
  
  	    while (--delta >= 0) {
  	      boolean b = tenum.next();
  	      if (b==false) {
  	        t = null;
  	        return false;
  	      }
  	      ++pos;
  	    }
  	    
  	    return setTerm();
  	  }
  
  	  /** The current term number, starting at 0.
  	   * Only valid if the previous call to next() or skipTo() returned true.
  	   */
  	  public int getTermNumber() {
  	    return pos;
  	  }
  	}
  