pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / src / java / org / apache / lucene / index / SegmentTermEnum.java
1 package org.apache.lucene.index;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import java.io.IOException;
21 import org.apache.lucene.store.IndexInput;
22
23 final class SegmentTermEnum extends TermEnum implements Cloneable {
24   private IndexInput input;
25   FieldInfos fieldInfos;
26   long size;
27   long position = -1;
28   private boolean first = true;
29
30   private TermBuffer termBuffer = new TermBuffer();
31   private TermBuffer prevBuffer = new TermBuffer();
32   private TermBuffer scanBuffer = new TermBuffer(); // used for scanning
33
34   private TermInfo termInfo = new TermInfo();
35
36   private int format;
37   private boolean isIndex = false;
38   long indexPointer = 0;
39   int indexInterval;
40   int skipInterval;
41   int maxSkipLevels;
42   private int formatM1SkipInterval;
43
44   SegmentTermEnum(IndexInput i, FieldInfos fis, boolean isi)
45           throws CorruptIndexException, IOException {
46     input = i;
47     fieldInfos = fis;
48     isIndex = isi;
49     maxSkipLevels = 1; // use single-level skip lists for formats > -3 
50     
51     int firstInt = input.readInt();
52     if (firstInt >= 0) {
53       // original-format file, without explicit format version number
54       format = 0;
55       size = firstInt;
56
57       // back-compatible settings
58       indexInterval = 128;
59       skipInterval = Integer.MAX_VALUE; // switch off skipTo optimization
60     } else {
61       // we have a format version number
62       format = firstInt;
63
64       // check that it is a format we can understand
65       if (format < TermInfosWriter.FORMAT_CURRENT)
66         throw new IndexFormatTooNewException(input, format, -1, TermInfosWriter.FORMAT_CURRENT);
67
68       size = input.readLong();                    // read the size
69       
70       if(format == -1){
71         if (!isIndex) {
72           indexInterval = input.readInt();
73           formatM1SkipInterval = input.readInt();
74         }
75         // switch off skipTo optimization for file format prior to 1.4rc2 in order to avoid a bug in 
76         // skipTo implementation of these versions
77         skipInterval = Integer.MAX_VALUE;
78       } else {
79         indexInterval = input.readInt();
80         skipInterval = input.readInt();
81         if (format <= TermInfosWriter.FORMAT) {
82           // this new format introduces multi-level skipping
83           maxSkipLevels = input.readInt();
84         }
85       }
86       assert indexInterval > 0: "indexInterval=" + indexInterval + " is negative; must be > 0";
87       assert skipInterval > 0: "skipInterval=" + skipInterval + " is negative; must be > 0";
88     }
89     if (format > TermInfosWriter.FORMAT_VERSION_UTF8_LENGTH_IN_BYTES) {
90       termBuffer.setPreUTF8Strings();
91       scanBuffer.setPreUTF8Strings();
92       prevBuffer.setPreUTF8Strings();
93     }
94   }
95
96   @Override
97   protected Object clone() {
98     SegmentTermEnum clone = null;
99     try {
100       clone = (SegmentTermEnum) super.clone();
101     } catch (CloneNotSupportedException e) {}
102
103     clone.input = (IndexInput) input.clone();
104     clone.termInfo = new TermInfo(termInfo);
105
106     clone.termBuffer = (TermBuffer)termBuffer.clone();
107     clone.prevBuffer = (TermBuffer)prevBuffer.clone();
108     clone.scanBuffer = new TermBuffer();
109
110     return clone;
111   }
112
113   final void seek(long pointer, long p, Term t, TermInfo ti)
114           throws IOException {
115     input.seek(pointer);
116     position = p;
117     termBuffer.set(t);
118     prevBuffer.reset();
119     termInfo.set(ti);
120     first = p == -1;
121   }
122
123   /** Increments the enumeration to the next element.  True if one exists.*/
124   @Override
125   public final boolean next() throws IOException {
126     if (position++ >= size - 1) {
127       prevBuffer.set(termBuffer);
128       termBuffer.reset();
129       return false;
130     }
131
132     prevBuffer.set(termBuffer);
133     termBuffer.read(input, fieldInfos);
134
135     termInfo.docFreq = input.readVInt();          // read doc freq
136     termInfo.freqPointer += input.readVLong();    // read freq pointer
137     termInfo.proxPointer += input.readVLong();    // read prox pointer
138     
139     if(format == -1){
140     //  just read skipOffset in order to increment  file pointer; 
141     // value is never used since skipTo is switched off
142       if (!isIndex) {
143         if (termInfo.docFreq > formatM1SkipInterval) {
144           termInfo.skipOffset = input.readVInt(); 
145         }
146       }
147     }
148     else{
149       if (termInfo.docFreq >= skipInterval) 
150         termInfo.skipOffset = input.readVInt();
151     }
152     
153     if (isIndex)
154       indexPointer += input.readVLong();          // read index pointer
155
156     return true;
157   }
158
159   /* Optimized scan, without allocating new terms. 
160    *  Return number of invocations to next().
161    *
162    * NOTE: LUCENE-3183: if you pass Term("", "") here then this
163    * will incorrectly return before positioning the enum,
164    * and position will be -1; caller must detect this. */
165   final int scanTo(Term term) throws IOException {
166     scanBuffer.set(term);
167     int count = 0;
168     if (first) {
169       // Always force initial next() in case term is Term("", "")
170       next();
171       first = false;
172       count++;
173     }
174     while (scanBuffer.compareTo(termBuffer) > 0 && next()) {
175       count++;
176     }
177     return count;
178   }
179
180   /** Returns the current Term in the enumeration.
181    Initially invalid, valid after next() called for the first time.*/
182   @Override
183   public final Term term() {
184     return termBuffer.toTerm();
185   }
186
187   /** Returns the previous Term enumerated. Initially null.*/
188   final Term prev() {
189     return prevBuffer.toTerm();
190   }
191
192   /** Returns the current TermInfo in the enumeration.
193    Initially invalid, valid after next() called for the first time.*/
194   final TermInfo termInfo() {
195     return new TermInfo(termInfo);
196   }
197
198   /** Sets the argument to the current TermInfo in the enumeration.
199    Initially invalid, valid after next() called for the first time.*/
200   final void termInfo(TermInfo ti) {
201     ti.set(termInfo);
202   }
203
204   /** Returns the docFreq from the current TermInfo in the enumeration.
205    Initially invalid, valid after next() called for the first time.*/
206   @Override
207   public final int docFreq() {
208     return termInfo.docFreq;
209   }
210
211   /* Returns the freqPointer from the current TermInfo in the enumeration.
212     Initially invalid, valid after next() called for the first time.*/
213   final long freqPointer() {
214     return termInfo.freqPointer;
215   }
216
217   /* Returns the proxPointer from the current TermInfo in the enumeration.
218     Initially invalid, valid after next() called for the first time.*/
219   final long proxPointer() {
220     return termInfo.proxPointer;
221   }
222
223   /** Closes the enumeration to further activity, freeing resources. */
224   @Override
225   public final void close() throws IOException {
226     input.close();
227   }
228 }