cvsimport
[beagle.git] / beagled / Lucene.Net / Index / SegmentTermDocs.cs
blob1c15e5c3caf83bb99414bc43a5f0a063fc63c703
1 /*
2 * Copyright 2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 using System;
18 using IndexInput = Lucene.Net.Store.IndexInput;
19 using BitVector = Lucene.Net.Util.BitVector;
21 namespace Lucene.Net.Index
24 public class SegmentTermDocs : TermDocs
26 protected internal SegmentReader parent;
27 protected internal IndexInput freqStream;
28 protected internal int count;
29 protected internal int df;
30 protected internal BitVector deletedDocs;
31 internal int doc = 0;
32 internal int freq;
34 private int skipInterval;
35 private int numSkips;
36 private int skipCount;
37 private IndexInput skipStream;
38 private int skipDoc;
39 private long freqPointer;
40 private long proxPointer;
41 private long skipPointer;
42 private bool haveSkipped;
44 public SegmentTermDocs(SegmentReader parent)
46 this.parent = parent;
47 this.freqStream = (IndexInput) parent.freqStream.Clone();
48 this.deletedDocs = parent.deletedDocs;
49 this.skipInterval = parent.tis.GetSkipInterval();
52 public virtual void Seek(Term term)
54 TermInfo ti = parent.tis.Get(term);
55 Seek(ti);
58 public virtual void Seek(TermEnum termEnum)
60 TermInfo ti;
62 // use comparison of fieldinfos to verify that termEnum belongs to the same segment as this SegmentTermDocs
63 if (termEnum is SegmentTermEnum && ((SegmentTermEnum) termEnum).fieldInfos == parent.fieldInfos)
64 // optimized case
65 ti = ((SegmentTermEnum) termEnum).TermInfo();
66 // punt case
67 else
68 ti = parent.tis.Get(termEnum.Term());
70 Seek(ti);
73 internal virtual void Seek(TermInfo ti)
75 count = 0;
76 if (ti == null)
78 df = 0;
80 else
82 df = ti.docFreq;
83 doc = 0;
84 skipDoc = 0;
85 skipCount = 0;
86 numSkips = df / skipInterval;
87 freqPointer = ti.freqPointer;
88 proxPointer = ti.proxPointer;
89 skipPointer = freqPointer + ti.skipOffset;
90 freqStream.Seek(freqPointer);
91 haveSkipped = false;
95 public virtual void Close()
97 freqStream.Close();
98 if (skipStream != null)
99 skipStream.Close();
102 public int Doc()
104 return doc;
106 public int Freq()
108 return freq;
111 protected internal virtual void SkippingDoc()
115 public virtual bool Next()
117 while (true)
119 if (count == df)
120 return false;
122 int docCode = freqStream.ReadVInt();
123 doc += (int) (((uint) docCode) >> 1); // shift off low bit
124 if ((docCode & 1) != 0)
125 // if low bit is set
126 freq = 1;
127 // freq is one
128 else
129 freq = freqStream.ReadVInt(); // else read freq
131 count++;
133 if (deletedDocs == null || !deletedDocs.Get(doc))
134 break;
135 SkippingDoc();
137 return true;
140 /// <summary>Optimized implementation. </summary>
141 public virtual int Read(int[] docs, int[] freqs)
143 int length = docs.Length;
144 int i = 0;
145 while (i < length && count < df)
148 // manually inlined call to next() for speed
149 int docCode = freqStream.ReadVInt();
150 doc += (int) (((uint) docCode) >> 1); // shift off low bit
151 if ((docCode & 1) != 0)
152 // if low bit is set
153 freq = 1;
154 // freq is one
155 else
156 freq = freqStream.ReadVInt(); // else read freq
157 count++;
159 if (deletedDocs == null || !deletedDocs.Get(doc))
161 docs[i] = doc;
162 freqs[i] = freq;
163 ++i;
166 return i;
169 /// <summary>Overridden by SegmentTermPositions to skip in prox stream. </summary>
170 protected internal virtual void SkipProx(long proxPointer)
174 /// <summary>Optimized implementation. </summary>
175 public virtual bool SkipTo(int target)
177 if (df >= skipInterval)
179 // optimized case
181 if (skipStream == null)
182 skipStream = (IndexInput) freqStream.Clone(); // lazily clone
184 if (!haveSkipped)
186 // lazily seek skip stream
187 skipStream.Seek(skipPointer);
188 haveSkipped = true;
191 // scan skip data
192 int lastSkipDoc = skipDoc;
193 long lastFreqPointer = freqStream.GetFilePointer();
194 long lastProxPointer = - 1;
195 int numSkipped = - 1 - (count % skipInterval);
197 while (target > skipDoc)
199 lastSkipDoc = skipDoc;
200 lastFreqPointer = freqPointer;
201 lastProxPointer = proxPointer;
203 if (skipDoc != 0 && skipDoc >= doc)
204 numSkipped += skipInterval;
206 if (skipCount >= numSkips)
207 break;
209 skipDoc += skipStream.ReadVInt();
210 freqPointer += skipStream.ReadVInt();
211 proxPointer += skipStream.ReadVInt();
213 skipCount++;
216 // if we found something to skip, then skip it
217 if (lastFreqPointer > freqStream.GetFilePointer())
219 freqStream.Seek(lastFreqPointer);
220 SkipProx(lastProxPointer);
222 doc = lastSkipDoc;
223 count += numSkipped;
227 // done skipping, now just scan
230 if (!Next())
231 return false;
233 while (target > doc);
234 return true;