Merge pull request #409 from Alkarex/patch-1
[mono.git] / mcs / tools / monkeydoc / Lucene.Net / Lucene.Net / Index / SegmentTermEnum.cs
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
20 using IndexInput = Mono.Lucene.Net.Store.IndexInput;
21
22 namespace Mono.Lucene.Net.Index
23 {
24         
25         public sealed class SegmentTermEnum:TermEnum, System.ICloneable
26         {
27                 private IndexInput input;
28                 internal FieldInfos fieldInfos;
29                 internal long size;
30                 internal long position = - 1;
31                 
32                 private TermBuffer termBuffer = new TermBuffer();
33                 private TermBuffer prevBuffer = new TermBuffer();
34                 private TermBuffer scanBuffer = new TermBuffer(); // used for scanning
35                 
36                 private TermInfo termInfo = new TermInfo();
37                 
38                 private int format;
39                 private bool isIndex = false;
40                 internal long indexPointer = 0;
41                 internal int indexInterval;
42                 internal int skipInterval;
43                 internal int maxSkipLevels;
44                 private int formatM1SkipInterval;
45                 
46                 internal SegmentTermEnum(IndexInput i, FieldInfos fis, bool isi)
47                 {
48                         input = i;
49                         fieldInfos = fis;
50                         isIndex = isi;
51                         maxSkipLevels = 1; // use single-level skip lists for formats > -3 
52                         
53                         int firstInt = input.ReadInt();
54                         if (firstInt >= 0)
55                         {
56                                 // original-format file, without explicit format version number
57                                 format = 0;
58                                 size = firstInt;
59                                 
60                                 // back-compatible settings
61                                 indexInterval = 128;
62                                 skipInterval = System.Int32.MaxValue; // switch off skipTo optimization
63                         }
64                         else
65                         {
66                                 // we have a format version number
67                                 format = firstInt;
68                                 
69                                 // check that it is a format we can understand
70                                 if (format < TermInfosWriter.FORMAT_CURRENT)
71                                         throw new CorruptIndexException("Unknown format version:" + format + " expected " + TermInfosWriter.FORMAT_CURRENT + " or higher");
72                                 
73                                 size = input.ReadLong(); // read the size
74                                 
75                                 if (format == - 1)
76                                 {
77                                         if (!isIndex)
78                                         {
79                                                 indexInterval = input.ReadInt();
80                                                 formatM1SkipInterval = input.ReadInt();
81                                         }
82                                         // switch off skipTo optimization for file format prior to 1.4rc2 in order to avoid a bug in 
83                                         // skipTo implementation of these versions
84                                         skipInterval = System.Int32.MaxValue;
85                                 }
86                                 else
87                                 {
88                                         indexInterval = input.ReadInt();
89                                         skipInterval = input.ReadInt();
90                                         if (format <= TermInfosWriter.FORMAT)
91                                         {
92                                                 // this new format introduces multi-level skipping
93                                                 maxSkipLevels = input.ReadInt();
94                                         }
95                                 }
96                                 System.Diagnostics.Debug.Assert(indexInterval > 0, "indexInterval=" + indexInterval + " is negative; must be > 0");
97                                 System.Diagnostics.Debug.Assert(skipInterval > 0, "skipInterval=" + skipInterval + " is negative; must be > 0");
98                         }
99                         if (format > TermInfosWriter.FORMAT_VERSION_UTF8_LENGTH_IN_BYTES)
100                         {
101                                 termBuffer.SetPreUTF8Strings();
102                                 scanBuffer.SetPreUTF8Strings();
103                                 prevBuffer.SetPreUTF8Strings();
104                         }
105                 }
106                 
107                 public System.Object Clone()
108                 {
109                         SegmentTermEnum clone = null;
110                         try
111                         {
112                                 clone = (SegmentTermEnum) base.MemberwiseClone();
113                         }
114                         catch (System.Exception e)
115                         {
116                         }
117                         
118                         clone.input = (IndexInput) input.Clone();
119                         clone.termInfo = new TermInfo(termInfo);
120                         
121                         clone.termBuffer = (TermBuffer) termBuffer.Clone();
122                         clone.prevBuffer = (TermBuffer) prevBuffer.Clone();
123                         clone.scanBuffer = new TermBuffer();
124                         
125                         return clone;
126                 }
127                 
128                 internal void  Seek(long pointer, long p, Term t, TermInfo ti)
129                 {
130                         input.Seek(pointer);
131                         position = p;
132                         termBuffer.Set(t);
133                         prevBuffer.Reset();
134                         termInfo.Set(ti);
135                 }
136                 
137                 /// <summary>Increments the enumeration to the next element.  True if one exists.</summary>
138                 public override bool Next()
139                 {
140                         if (position++ >= size - 1)
141                         {
142                                 prevBuffer.Set(termBuffer);
143                                 termBuffer.Reset();
144                                 return false;
145                         }
146                         
147                         prevBuffer.Set(termBuffer);
148                         termBuffer.Read(input, fieldInfos);
149                         
150                         termInfo.docFreq = input.ReadVInt(); // read doc freq
151                         termInfo.freqPointer += input.ReadVLong(); // read freq pointer
152                         termInfo.proxPointer += input.ReadVLong(); // read prox pointer
153                         
154                         if (format == - 1)
155                         {
156                                 //  just read skipOffset in order to increment  file pointer; 
157                                 // value is never used since skipTo is switched off
158                                 if (!isIndex)
159                                 {
160                                         if (termInfo.docFreq > formatM1SkipInterval)
161                                         {
162                                                 termInfo.skipOffset = input.ReadVInt();
163                                         }
164                                 }
165                         }
166                         else
167                         {
168                                 if (termInfo.docFreq >= skipInterval)
169                                         termInfo.skipOffset = input.ReadVInt();
170                         }
171                         
172                         if (isIndex)
173                                 indexPointer += input.ReadVLong(); // read index pointer
174                         
175                         return true;
176                 }
177                 
178                 /// <summary>Optimized scan, without allocating new terms. 
179                 /// Return number of invocations to next(). 
180                 /// </summary>
181                 internal int ScanTo(Term term)
182                 {
183                         scanBuffer.Set(term);
184                         int count = 0;
185                         while (scanBuffer.CompareTo(termBuffer) > 0 && Next())
186                         {
187                                 count++;
188                         }
189                         return count;
190                 }
191                 
192                 /// <summary>Returns the current Term in the enumeration.
193                 /// Initially invalid, valid after next() called for the first time.
194                 /// </summary>
195                 public override Term Term()
196                 {
197                         return termBuffer.ToTerm();
198                 }
199                 
200                 /// <summary>Returns the previous Term enumerated. Initially null.</summary>
201                 public /*internal*/ Term Prev()
202                 {
203                         return prevBuffer.ToTerm();
204                 }
205                 
206                 /// <summary>Returns the current TermInfo in the enumeration.
207                 /// Initially invalid, valid after next() called for the first time.
208                 /// </summary>
209                 internal TermInfo TermInfo()
210                 {
211                         return new TermInfo(termInfo);
212                 }
213                 
214                 /// <summary>Sets the argument to the current TermInfo in the enumeration.
215                 /// Initially invalid, valid after next() called for the first time.
216                 /// </summary>
217                 internal void  TermInfo(TermInfo ti)
218                 {
219                         ti.Set(termInfo);
220                 }
221                 
222                 /// <summary>Returns the docFreq from the current TermInfo in the enumeration.
223                 /// Initially invalid, valid after next() called for the first time.
224                 /// </summary>
225                 public override int DocFreq()
226                 {
227                         return termInfo.docFreq;
228                 }
229                 
230                 /* Returns the freqPointer from the current TermInfo in the enumeration.
231                 Initially invalid, valid after next() called for the first time.*/
232                 internal long FreqPointer()
233                 {
234                         return termInfo.freqPointer;
235                 }
236                 
237                 /* Returns the proxPointer from the current TermInfo in the enumeration.
238                 Initially invalid, valid after next() called for the first time.*/
239                 internal long ProxPointer()
240                 {
241                         return termInfo.proxPointer;
242                 }
243                 
244                 /// <summary>Closes the enumeration to further activity, freeing resources. </summary>
245                 public override void  Close()
246                 {
247                         input.Close();
248                 }
249         }
250 }