add --shared
[pylucene.git] / lucene-java-3.4.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
29   private TermBuffer termBuffer = new TermBuffer();
30   private TermBuffer prevBuffer = new TermBuffer();
31   private TermBuffer scanBuffer = new TermBuffer(); // used for scanning
32
33   private TermInfo termInfo = new TermInfo();
34
35   private int format;
36   private boolean isIndex = false;
37   long indexPointer = 0;
38   int indexInterval;
39   int skipInterval;
40   int maxSkipLevels;
41   private int formatM1SkipInterval;
42
43   SegmentTermEnum(IndexInput i, FieldInfos fis, boolean isi)
44           throws CorruptIndexException, IOException {
45     input = i;
46     fieldInfos = fis;
47     isIndex = isi;
48     maxSkipLevels = 1; // use single-level skip lists for formats > -3 
49     
50     int firstInt = input.readInt();
51     if (firstInt >= 0) {
52       // original-format file, without explicit format version number
53       format = 0;
54       size = firstInt;
55
56       // back-compatible settings
57       indexInterval = 128;
58       skipInterval = Integer.MAX_VALUE; // switch off skipTo optimization
59     } else {
60       // we have a format version number
61       format = firstInt;
62
63       // check that it is a format we can understand
64       if (format < TermInfosWriter.FORMAT_CURRENT)
65         throw new CorruptIndexException("Unknown format version:" + format + " expected " + TermInfosWriter.FORMAT_CURRENT + " or higher");
66
67       size = input.readLong();                    // read the size
68       
69       if(format == -1){
70         if (!isIndex) {
71           indexInterval = input.readInt();
72           formatM1SkipInterval = input.readInt();
73         }
74         // switch off skipTo optimization for file format prior to 1.4rc2 in order to avoid a bug in 
75         // skipTo implementation of these versions
76         skipInterval = Integer.MAX_VALUE;
77       } else {
78         indexInterval = input.readInt();
79         skipInterval = input.readInt();
80         if (format <= TermInfosWriter.FORMAT) {
81           // this new format introduces multi-level skipping
82           maxSkipLevels = input.readInt();
83         }
84       }
85       assert indexInterval > 0: "indexInterval=" + indexInterval + " is negative; must be > 0";
86       assert skipInterval > 0: "skipInterval=" + skipInterval + " is negative; must be > 0";
87     }
88     if (format > TermInfosWriter.FORMAT_VERSION_UTF8_LENGTH_IN_BYTES) {
89       termBuffer.setPreUTF8Strings();
90       scanBuffer.setPreUTF8Strings();
91       prevBuffer.setPreUTF8Strings();
92     }
93   }
94
95   @Override
96   protected Object clone() {
97     SegmentTermEnum clone = null;
98     try {
99       clone = (SegmentTermEnum) super.clone();
100     } catch (CloneNotSupportedException e) {}
101
102     clone.input = (IndexInput) input.clone();
103     clone.termInfo = new TermInfo(termInfo);
104
105     clone.termBuffer = (TermBuffer)termBuffer.clone();
106     clone.prevBuffer = (TermBuffer)prevBuffer.clone();
107     clone.scanBuffer = new TermBuffer();
108
109     return clone;
110   }
111
112   final void seek(long pointer, long p, Term t, TermInfo ti)
113           throws IOException {
114     input.seek(pointer);
115     position = p;
116     termBuffer.set(t);
117     prevBuffer.reset();
118     termInfo.set(ti);
119   }
120
121   /** Increments the enumeration to the next element.  True if one exists.*/
122   @Override
123   public final boolean next() throws IOException {
124     if (position++ >= size - 1) {
125       prevBuffer.set(termBuffer);
126       termBuffer.reset();
127       return false;
128     }
129
130     prevBuffer.set(termBuffer);
131     termBuffer.read(input, fieldInfos);
132
133     termInfo.docFreq = input.readVInt();          // read doc freq
134     termInfo.freqPointer += input.readVLong();    // read freq pointer
135     termInfo.proxPointer += input.readVLong();    // read prox pointer
136     
137     if(format == -1){
138     //  just read skipOffset in order to increment  file pointer; 
139     // value is never used since skipTo is switched off
140       if (!isIndex) {
141         if (termInfo.docFreq > formatM1SkipInterval) {
142           termInfo.skipOffset = input.readVInt(); 
143         }
144       }
145     }
146     else{
147       if (termInfo.docFreq >= skipInterval) 
148         termInfo.skipOffset = input.readVInt();
149     }
150     
151     if (isIndex)
152       indexPointer += input.readVLong();          // read index pointer
153
154     return true;
155   }
156
157   /* Optimized scan, without allocating new terms. 
158    *  Return number of invocations to next().
159    *
160    * NOTE: LUCENE-3183: if you pass Term("", "") here then this
161    * will incorrectly return before positioning the enum,
162    * and position will be -1; caller must detect this. */
163   final int scanTo(Term term) throws IOException {
164     scanBuffer.set(term);
165     int count = 0;
166     while (scanBuffer.compareTo(termBuffer) > 0 && next()) {
167       count++;
168     }
169     return count;
170   }
171
172   /** Returns the current Term in the enumeration.
173    Initially invalid, valid after next() called for the first time.*/
174   @Override
175   public final Term term() {
176     return termBuffer.toTerm();
177   }
178
179   /** Returns the previous Term enumerated. Initially null.*/
180   final Term prev() {
181     return prevBuffer.toTerm();
182   }
183
184   /** Returns the current TermInfo in the enumeration.
185    Initially invalid, valid after next() called for the first time.*/
186   final TermInfo termInfo() {
187     return new TermInfo(termInfo);
188   }
189
190   /** Sets the argument to the current TermInfo in the enumeration.
191    Initially invalid, valid after next() called for the first time.*/
192   final void termInfo(TermInfo ti) {
193     ti.set(termInfo);
194   }
195
196   /** Returns the docFreq from the current TermInfo in the enumeration.
197    Initially invalid, valid after next() called for the first time.*/
198   @Override
199   public final int docFreq() {
200     return termInfo.docFreq;
201   }
202
203   /* Returns the freqPointer from the current TermInfo in the enumeration.
204     Initially invalid, valid after next() called for the first time.*/
205   final long freqPointer() {
206     return termInfo.freqPointer;
207   }
208
209   /* Returns the proxPointer from the current TermInfo in the enumeration.
210     Initially invalid, valid after next() called for the first time.*/
211   final long proxPointer() {
212     return termInfo.proxPointer;
213   }
214
215   /** Closes the enumeration to further activity, freeing resources. */
216   @Override
217   public final void close() throws IOException {
218     input.close();
219   }
220 }