content: package org.apache.lucene.index;
  
  
  import java.io.IOException;
  
  import org.apache.lucene.store.IndexInput;
  import org.apache.lucene.util.BytesRef;
  
  
  /**
   * This stores a monotonically increasing set of <Term, TermInfo> pairs in an
   * index segment. Pairs are accessed either by Term or by ordinal position the
   * set. The Terms and TermInfo are actually serialized and stored into a byte
   * array and pointers to the position of each are stored in a int array.
   */
  class TermInfosReaderIndexQuick implements TermInfoReaderIndexInterface{
  	TermBuffer buff=new TermBuffer();
  	private static long HEAD_SIZE=(Integer.SIZE*4+Long.SIZE*1)/8;
  	private static long ITEM_SIZE=(Integer.SIZE*2+Long.SIZE*4)/8;
  	  public static class TiiInfo{
  		  int docFreq;
  		  long freqPointer;
  		  long proxPointer;
  		  int skipOffset;
  		  long tispos;
  		  long qtiipos;
  		  Term tm;
  	  }
    private TiiInfo[] termInfoArr;
    private int totalIndexInterval;
    private final int skipInterval;
    IndexInput tiiInput;
    IndexInput quickTii;
    FieldInfos fieldInfos;
    private final int indexSize;
  
    TermInfosReaderIndexQuick( IndexInput tiiInput,IndexInput quickTii,  FieldInfos fieldInfos,long tiifilesize, int indexDivisor, long tiiFileLength, int totalIndexInterval) throws IOException {
  	 this.tiiInput=tiiInput;
  	 this.quickTii=quickTii;
  	 this.fieldInfos=fieldInfos;
      this.totalIndexInterval = totalIndexInterval;
   
      
      int FORMAT_CURRENT=tiiInput.readInt();
      
      if (FORMAT_CURRENT > TermInfosWriter.FORMAT_VERSION_UTF8_LENGTH_IN_BYTES) {
      	buff.setPreUTF8Strings();
      }
  
      long QUICK_TII=tiiInput.readLong();
      int indexInterval=tiiInput.readInt();
      skipInterval=tiiInput.readInt();
      int maxSkipLevels=tiiInput.readInt();
      termInfoArr = new TiiInfo[(int) tiifilesize];
      
      indexSize = 1 + ((int) tiifilesize - 1) / indexDivisor;
  
    }
  
  
    public void seekEnum(SegmentTermEnum enumerator, int indexOffset) throws IOException {
  	  IndexInput tii= (IndexInput)this.tiiInput.clone();
  	  IndexInput qtii=(IndexInput)this.quickTii.clone();
  		TiiInfo ti=this.getTiiInfo(indexOffset, tii, qtii);
  
  
      // read the term
      Term term = ti.tm;
  
      // read the terminfo
      TermInfo termInfo = new TermInfo();
      termInfo.docFreq = ti.docFreq;
      if (termInfo.docFreq >= skipInterval) {
        termInfo.skipOffset = ti.skipOffset;
      } else {
        termInfo.skipOffset = 0;
      }
      termInfo.freqPointer = ti.freqPointer;
      termInfo.proxPointer =ti.proxPointer;
  
      long pointer =ti.tispos;
  
      // perform the seek
      enumerator.seek(pointer, ((long) indexOffset * totalIndexInterval) - 1, term, termInfo);
    }
  
    /**
     * Binary search for the given term.
     * 
     * @param term
     *          the term to locate.
     * @throws IOException 
     */
    public int getIndexOffset(Term term, BytesRef termBytesRef) throws IOException {
  	  IndexInput tii= (IndexInput)this.tiiInput.clone();
  	  IndexInput qtii=(IndexInput)this.quickTii.clone();
      int lo = 0;
      int hi = termInfoArr.length-1;
      while (hi >= lo) {
        int mid = (lo + hi) >>> 1;
        int delta = compareTo(term, termBytesRef, mid,tii, qtii,new BytesRef());
        if (delta < 0)
          hi = mid - 1;
        else if (delta > 0)
          lo = mid + 1;
        else
          return mid;
      }
      return hi;
    }
  
    
  
    public int length() {
      return indexSize;
    }
  
  
    public int compareTo(Term term, BytesRef termBytesRef, int termIndex) throws IOException {
      return compareTo(term, termBytesRef, termIndex,(IndexInput)this.tiiInput.clone(),(IndexInput)this.quickTii.clone(),new BytesRef());
    }
  
  
    private int compareTo(Term term, BytesRef termBytesRef, int termIndex, IndexInput tiiInput, IndexInput quickTii, BytesRef reuse) throws IOException {
  		 TiiInfo ti=this.getTiiInfo(termIndex, tiiInput, quickTii);
      return term.compareTo(ti.tm);
    }
  //  output.writeInt(ti.docFreq);                       // write doc freq
  //  output.writeLong(ti.freqPointer); // write pointers
  //  output.writeLong(ti.proxPointer);
  //  output.writeInt(ti.skipOffset);
  //  output.writeLong(other.output.getFilePointer());
  //  output.writeLong(this.outputQuickTii.getFilePointer());
  //  this.writeTermTii(fieldNumber, termBytes, termBytesLength);
    private TiiInfo getTiiInfo(int termIndex,   IndexInput tiiInput, IndexInput quickTii) throws IOException {
  	  TiiInfo ti=null;
  	  synchronized (this.termInfoArr) {
  		  ti=this.termInfoArr[termIndex];
  		  if(ti==null)
  		  {
  			  long pos=TermInfosReaderIndexQuick.HEAD_SIZE+termIndex*TermInfosReaderIndexQuick.ITEM_SIZE;
  			    tiiInput.seek(pos);
  	
  			    ti=new TiiInfo();
  			    ti.docFreq=tiiInput.readInt();
  			    ti.freqPointer=tiiInput.readLong();
  			    ti.proxPointer=tiiInput.readLong();
  			    ti.skipOffset=tiiInput.readInt();
  			    ti.tispos=tiiInput.readLong();
  			    ti.qtiipos=tiiInput.readLong();
  			    quickTii.seek(ti.qtiipos);
  			    buff.readTiiQuick(quickTii, fieldInfos);
  			    ti.tm=buff.toTerm();
  			    this.termInfoArr[termIndex]=ti;
  
  	  }
  	}
     
      return ti;
    }
  }
  