Thumbnail file hits. Based on a patch from D Bera
[beagle.git] / beagled / Lucene.Net / Index / SegmentTermDocs.cs
blob498dad3469c38a772228c72b23b60eb8984c9dd7
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.
16 using System;
17 using InputStream = Lucene.Net.Store.InputStream;
18 using BitVector = Lucene.Net.Util.BitVector;
19 namespace Lucene.Net.Index
22 public class SegmentTermDocs : TermDocs
24 protected internal SegmentReader parent;
25 private InputStream freqStream;
26 private int count;
27 private int df;
28 private BitVector deletedDocs;
29 internal int doc = 0;
30 internal int freq;
32 private int skipInterval;
33 private int numSkips;
34 private int skipCount;
35 private InputStream skipStream;
36 private int skipDoc;
37 private long freqPointer;
38 private long proxPointer;
39 private long skipPointer;
40 private bool haveSkipped;
42 public /*internal*/ SegmentTermDocs(SegmentReader parent)
44 this.parent = parent;
45 this.freqStream = (InputStream) parent.freqStream.Clone();
46 this.deletedDocs = parent.deletedDocs;
47 this.skipInterval = parent.tis.GetSkipInterval();
50 public virtual void Seek(Term term)
52 TermInfo ti = parent.tis.Get(term);
53 Seek(ti);
56 public virtual void Seek(TermEnum termEnum)
58 TermInfo ti;
60 // use comparison of fieldinfos to verify that termEnum belongs to the same segment as this SegmentTermDocs
61 if (termEnum is SegmentTermEnum && ((SegmentTermEnum) termEnum).fieldInfos == parent.fieldInfos)
62 // optimized case
63 ti = ((SegmentTermEnum) termEnum).TermInfo();
64 // punt case
65 else
66 ti = parent.tis.Get(termEnum.Term());
68 Seek(ti);
71 internal virtual void Seek(TermInfo ti)
73 count = 0;
74 if (ti == null)
76 df = 0;
78 else
80 df = ti.docFreq;
81 doc = 0;
82 skipDoc = 0;
83 skipCount = 0;
84 numSkips = df / skipInterval;
85 freqPointer = ti.freqPointer;
86 proxPointer = ti.proxPointer;
87 skipPointer = freqPointer + ti.skipOffset;
88 freqStream.Seek(freqPointer);
89 haveSkipped = false;
93 public virtual void Close()
95 freqStream.Close();
96 if (skipStream != null)
97 skipStream.Close();
100 public int Doc()
102 return doc;
104 public int Freq()
106 return freq;
109 protected internal virtual void SkippingDoc()
113 public virtual bool Next()
115 while (true)
117 if (count == df)
118 return false;
120 int docCode = freqStream.ReadVInt();
121 doc += (int) (((uint) docCode) >> 1); // shift off low bit
122 if ((docCode & 1) != 0)
123 // if low bit is set
124 freq = 1;
125 // freq is one
126 else
127 freq = freqStream.ReadVInt(); // else read freq
129 count++;
131 if (deletedDocs == null || !deletedDocs.Get(doc))
132 break;
133 SkippingDoc();
135 return true;
138 /// <summary>Optimized implementation. </summary>
139 public virtual int Read(int[] docs, int[] freqs)
141 int length = docs.Length;
142 int i = 0;
143 while (i < length && count < df)
146 // manually inlined call to next() for speed
147 int docCode = freqStream.ReadVInt();
148 doc += (int) (((uint) docCode) >> 1); // shift off low bit
149 if ((docCode & 1) != 0)
150 // if low bit is set
151 freq = 1;
152 // freq is one
153 else
154 freq = freqStream.ReadVInt(); // else read freq
155 count++;
157 if (deletedDocs == null || !deletedDocs.Get(doc))
159 docs[i] = doc;
160 freqs[i] = freq;
161 ++i;
164 return i;
167 /// <summary>Overridden by SegmentTermPositions to skip in prox stream. </summary>
168 protected internal virtual void SkipProx(long proxPointer)
172 /// <summary>Optimized implementation. </summary>
173 public virtual bool SkipTo(int target)
175 if (df >= skipInterval)
177 // optimized case
179 if (skipStream == null)
180 skipStream = (InputStream) freqStream.Clone(); // lazily clone
182 if (!haveSkipped)
184 // lazily seek skip stream
185 skipStream.Seek(skipPointer);
186 haveSkipped = true;
189 // scan skip data
190 int lastSkipDoc = skipDoc;
191 long lastFreqPointer = freqStream.GetFilePointer();
192 long lastProxPointer = - 1;
193 int numSkipped = - 1 - (count % skipInterval);
195 while (target > skipDoc)
197 lastSkipDoc = skipDoc;
198 lastFreqPointer = freqPointer;
199 lastProxPointer = proxPointer;
201 if (skipDoc != 0 && skipDoc >= doc)
202 numSkipped += skipInterval;
204 if (skipCount >= numSkips)
205 break;
207 skipDoc += skipStream.ReadVInt();
208 freqPointer += skipStream.ReadVInt();
209 proxPointer += skipStream.ReadVInt();
211 skipCount++;
214 // if we found something to skip, then skip it
215 if (lastFreqPointer > freqStream.GetFilePointer())
217 freqStream.Seek(lastFreqPointer);
218 SkipProx(lastProxPointer);
220 doc = lastSkipDoc;
221 count += numSkipped;
225 // done skipping, now just scan
228 if (!Next())
229 return false;
231 while (target > doc);
232 return true;