Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
SegmentTermDocs.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System;
19 using Lucene.Net.Support;
20 using IndexInput = Lucene.Net.Store.IndexInput;
21 using BitVector = Lucene.Net.Util.BitVector;
22 
23 namespace Lucene.Net.Index
24 {
25 
26  internal class SegmentTermDocs : TermDocs
27  {
28  protected internal SegmentReader parent;
29  protected internal IndexInput freqStream;
30  protected internal int count;
31  protected internal int df;
32  protected internal BitVector deletedDocs;
33  internal int doc = 0;
34  internal int freq;
35 
36  private readonly int skipInterval;
37  private readonly int maxSkipLevels;
38  private DefaultSkipListReader skipListReader;
39 
40  private long freqBasePointer;
41  private long proxBasePointer;
42 
43  private long skipPointer;
44  private bool haveSkipped;
45 
46  protected internal bool currentFieldStoresPayloads;
47  protected internal bool currentFieldOmitTermFreqAndPositions;
48 
49  private bool isDisposed;
50 
51  public /*protected internal*/ SegmentTermDocs(SegmentReader parent)
52  {
53  this.parent = parent;
54  this.freqStream = (IndexInput) parent.core.freqStream.Clone();
55  lock (parent)
56  {
57  this.deletedDocs = parent.deletedDocs;
58  }
59  this.skipInterval = parent.core.GetTermsReader().SkipInterval;
60  this.maxSkipLevels = parent.core.GetTermsReader().MaxSkipLevels;
61  }
62 
63  public virtual void Seek(Term term)
64  {
65  TermInfo ti = parent.core.GetTermsReader().Get(term);
66  Seek(ti, term);
67  }
68 
69  public virtual void Seek(TermEnum termEnum)
70  {
71  TermInfo ti;
72  Term term;
73 
74  // use comparison of fieldinfos to verify that termEnum belongs to the same segment as this SegmentTermDocs
75  if (termEnum is SegmentTermEnum && ((SegmentTermEnum) termEnum).fieldInfos == parent.core.fieldInfos)
76  {
77  // optimized case
78  var segmentTermEnum = ((SegmentTermEnum) termEnum);
79  term = segmentTermEnum.Term;
80  ti = segmentTermEnum.TermInfo();
81  }
82  else
83  {
84  // punt case
85  term = termEnum.Term;
86  ti = parent.core.GetTermsReader().Get(term);
87  }
88 
89  Seek(ti, term);
90  }
91 
92  internal virtual void Seek(TermInfo ti, Term term)
93  {
94  count = 0;
95  FieldInfo fi = parent.core.fieldInfos.FieldInfo(term.Field);
96  currentFieldOmitTermFreqAndPositions = (fi != null) && fi.omitTermFreqAndPositions;
97  currentFieldStoresPayloads = (fi != null) && fi.storePayloads;
98  if (ti == null)
99  {
100  df = 0;
101  }
102  else
103  {
104  df = ti.docFreq;
105  doc = 0;
106  freqBasePointer = ti.freqPointer;
107  proxBasePointer = ti.proxPointer;
108  skipPointer = freqBasePointer + ti.skipOffset;
109  freqStream.Seek(freqBasePointer);
110  haveSkipped = false;
111  }
112  }
113 
114  public void Dispose()
115  {
116  Dispose(true);
117  }
118 
119  [Obsolete("Use Dispose() instead")]
120  public void Close()
121  {
122  Dispose();
123  }
124 
125  protected virtual void Dispose(bool disposing)
126  {
127  if (isDisposed) return;
128 
129  freqStream.Dispose();
130  if (skipListReader != null)
131  skipListReader.Dispose();
132 
133  isDisposed = true;
134  }
135 
136  public int Doc
137  {
138  get { return doc; }
139  }
140 
141  public int Freq
142  {
143  get { return freq; }
144  }
145 
146  protected internal virtual void SkippingDoc()
147  {
148  }
149 
150  public virtual bool Next()
151  {
152  while (true)
153  {
154  if (count == df)
155  return false;
156  int docCode = freqStream.ReadVInt();
157 
158  if (currentFieldOmitTermFreqAndPositions)
159  {
160  doc += docCode;
161  freq = 1;
162  }
163  else
164  {
165  doc += Number.URShift(docCode, 1); // shift off low bit
166  if ((docCode & 1) != 0)
167  // if low bit is set
168  freq = 1;
169  // freq is one
170  else
171  freq = freqStream.ReadVInt(); // else read freq
172  }
173 
174  count++;
175 
176  if (deletedDocs == null || !deletedDocs.Get(doc))
177  break;
178  SkippingDoc();
179  }
180  return true;
181  }
182 
183  /// <summary>Optimized implementation. </summary>
184  public virtual int Read(int[] docs, int[] freqs)
185  {
186  int length = docs.Length;
187  if (currentFieldOmitTermFreqAndPositions)
188  {
189  return ReadNoTf(docs, freqs, length);
190  }
191  else
192  {
193  int i = 0;
194  while (i < length && count < df)
195  {
196  // manually inlined call to next() for speed
197  int docCode = freqStream.ReadVInt();
198  doc += Number.URShift(docCode, 1); // shift off low bit
199  if ((docCode & 1) != 0)
200  // if low bit is set
201  freq = 1;
202  // freq is one
203  else
204  freq = freqStream.ReadVInt(); // else read freq
205  count++;
206 
207  if (deletedDocs == null || !deletedDocs.Get(doc))
208  {
209  docs[i] = doc;
210  freqs[i] = freq;
211  ++i;
212  }
213  }
214  return i;
215  }
216  }
217 
218  private int ReadNoTf(int[] docs, int[] freqs, int length)
219  {
220  int i = 0;
221  while (i < length && count < df)
222  {
223  // manually inlined call to next() for speed
224  doc += freqStream.ReadVInt();
225  count++;
226 
227  if (deletedDocs == null || !deletedDocs.Get(doc))
228  {
229  docs[i] = doc;
230  // Hardware freq to 1 when term freqs were not
231  // stored in the index
232  freqs[i] = 1;
233  ++i;
234  }
235  }
236  return i;
237  }
238 
239 
240  /// <summary>Overridden by SegmentTermPositions to skip in prox stream. </summary>
241  protected internal virtual void SkipProx(long proxPointer, int payloadLength)
242  {
243  }
244 
245  /// <summary>Optimized implementation. </summary>
246  public virtual bool SkipTo(int target)
247  {
248  if (df >= skipInterval)
249  {
250  // optimized case
251  if (skipListReader == null)
252  skipListReader = new DefaultSkipListReader((IndexInput) freqStream.Clone(), maxSkipLevels, skipInterval); // lazily clone
253 
254  if (!haveSkipped)
255  {
256  // lazily initialize skip stream
257  skipListReader.Init(skipPointer, freqBasePointer, proxBasePointer, df, currentFieldStoresPayloads);
258  haveSkipped = true;
259  }
260 
261  int newCount = skipListReader.SkipTo(target);
262  if (newCount > count)
263  {
264  freqStream.Seek(skipListReader.GetFreqPointer());
265  SkipProx(skipListReader.GetProxPointer(), skipListReader.GetPayloadLength());
266 
267  doc = skipListReader.GetDoc();
268  count = newCount;
269  }
270  }
271 
272  // done skipping, now just scan
273  do
274  {
275  if (!Next())
276  return false;
277  }
278  while (target > doc);
279  return true;
280  }
281  }
282 }