add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / src / java / org / apache / lucene / index / SegmentTermDocs.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.util.BitVector;
22 import org.apache.lucene.index.FieldInfo.IndexOptions;
23 import org.apache.lucene.store.IndexInput;
24
25 class SegmentTermDocs implements TermDocs {
26   protected SegmentReader parent;
27   protected IndexInput freqStream;
28   protected int count;
29   protected int df;
30   protected BitVector deletedDocs;
31   int doc = 0;
32   int freq;
33
34   private int skipInterval;
35   private int maxSkipLevels;
36   private DefaultSkipListReader skipListReader;
37   
38   private long freqBasePointer;
39   private long proxBasePointer;
40
41   private long skipPointer;
42   private boolean haveSkipped;
43   
44   protected boolean currentFieldStoresPayloads;
45   protected IndexOptions indexOptions;
46   
47   protected SegmentTermDocs(SegmentReader parent) {
48     this.parent = parent;
49     this.freqStream = (IndexInput) parent.core.freqStream.clone();
50     synchronized (parent) {
51       this.deletedDocs = parent.deletedDocs;
52     }
53     this.skipInterval = parent.core.getTermsReader().getSkipInterval();
54     this.maxSkipLevels = parent.core.getTermsReader().getMaxSkipLevels();
55   }
56
57   public void seek(Term term) throws IOException {
58     TermInfo ti = parent.core.getTermsReader().get(term);
59     seek(ti, term);
60   }
61
62   public void seek(TermEnum termEnum) throws IOException {
63     TermInfo ti;
64     Term term;
65     
66     // use comparison of fieldinfos to verify that termEnum belongs to the same segment as this SegmentTermDocs
67     if (termEnum instanceof SegmentTermEnum && ((SegmentTermEnum) termEnum).fieldInfos == parent.core.fieldInfos) {        // optimized case
68       SegmentTermEnum segmentTermEnum = ((SegmentTermEnum) termEnum);
69       term = segmentTermEnum.term();
70       ti = segmentTermEnum.termInfo();
71     } else  {                                         // punt case
72       term = termEnum.term();
73       ti = parent.core.getTermsReader().get(term);
74     }
75     
76     seek(ti, term);
77   }
78
79   void seek(TermInfo ti, Term term) throws IOException {
80     count = 0;
81     FieldInfo fi = parent.core.fieldInfos.fieldInfo(term.field);
82     indexOptions = (fi != null) ? fi.indexOptions : IndexOptions.DOCS_AND_FREQS_AND_POSITIONS;
83     currentFieldStoresPayloads = (fi != null) ? fi.storePayloads : false;
84     if (ti == null) {
85       df = 0;
86     } else {
87       df = ti.docFreq;
88       doc = 0;
89       freqBasePointer = ti.freqPointer;
90       proxBasePointer = ti.proxPointer;
91       skipPointer = freqBasePointer + ti.skipOffset;
92       freqStream.seek(freqBasePointer);
93       haveSkipped = false;
94     }
95   }
96
97   public void close() throws IOException {
98     freqStream.close();
99     if (skipListReader != null)
100       skipListReader.close();
101   }
102
103   public final int doc() { return doc; }
104   public final int freq() { return freq; }
105
106   protected void skippingDoc() throws IOException {
107   }
108
109   public boolean next() throws IOException {
110     while (true) {
111       if (count == df)
112         return false;
113       final int docCode = freqStream.readVInt();
114       
115       if (indexOptions == IndexOptions.DOCS_ONLY) {
116         doc += docCode;
117         freq = 1;
118       } else {
119         doc += docCode >>> 1;       // shift off low bit
120         if ((docCode & 1) != 0)       // if low bit is set
121           freq = 1;         // freq is one
122         else
123           freq = freqStream.readVInt();     // else read freq
124       }
125       
126       count++;
127
128       if (deletedDocs == null || !deletedDocs.get(doc))
129         break;
130       skippingDoc();
131     }
132     return true;
133   }
134
135   /** Optimized implementation. */
136   public int read(final int[] docs, final int[] freqs)
137           throws IOException {
138     final int length = docs.length;
139     if (indexOptions == IndexOptions.DOCS_ONLY) {
140       return readNoTf(docs, freqs, length);
141     } else {
142       int i = 0;
143       while (i < length && count < df) {
144         // manually inlined call to next() for speed
145         final int docCode = freqStream.readVInt();
146         doc += docCode >>> 1;       // shift off low bit
147         if ((docCode & 1) != 0)       // if low bit is set
148           freq = 1;         // freq is one
149         else
150           freq = freqStream.readVInt();     // else read freq
151         count++;
152
153         if (deletedDocs == null || !deletedDocs.get(doc)) {
154           docs[i] = doc;
155           freqs[i] = freq;
156           ++i;
157         }
158       }
159       return i;
160     }
161   }
162
163   private final int readNoTf(final int[] docs, final int[] freqs, final int length) throws IOException {
164     int i = 0;
165     while (i < length && count < df) {
166       // manually inlined call to next() for speed
167       doc += freqStream.readVInt();       
168       count++;
169
170       if (deletedDocs == null || !deletedDocs.get(doc)) {
171         docs[i] = doc;
172         // Hardware freq to 1 when term freqs were not
173         // stored in the index
174         freqs[i] = 1;
175         ++i;
176       }
177     }
178     return i;
179   }
180  
181   
182   /** Overridden by SegmentTermPositions to skip in prox stream. */
183   protected void skipProx(long proxPointer, int payloadLength) throws IOException {}
184
185   /** Optimized implementation. */
186   public boolean skipTo(int target) throws IOException {
187     if ((target - skipInterval) >= doc && df >= skipInterval) {                      // optimized case
188       if (skipListReader == null)
189         skipListReader = new DefaultSkipListReader((IndexInput) freqStream.clone(), maxSkipLevels, skipInterval); // lazily clone
190
191       if (!haveSkipped) {                          // lazily initialize skip stream
192         skipListReader.init(skipPointer, freqBasePointer, proxBasePointer, df, currentFieldStoresPayloads);
193         haveSkipped = true;
194       }
195
196       int newCount = skipListReader.skipTo(target); 
197       if (newCount > count) {
198         freqStream.seek(skipListReader.getFreqPointer());
199         skipProx(skipListReader.getProxPointer(), skipListReader.getPayloadLength());
200
201         doc = skipListReader.getDoc();
202         count = newCount;
203       }      
204     }
205
206     // done skipping, now just scan
207     do {
208       if (!next())
209         return false;
210     } while (target > doc);
211     return true;
212   }
213 }