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; } }