| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| using IndexInput = Lucene.Net.Store.IndexInput; |
| |
| namespace Lucene.Net.Index |
| { |
| internal sealed class SegmentTermEnum : TermEnum, System.ICloneable |
| { |
| private IndexInput input; |
| internal FieldInfos fieldInfos; |
| internal long size; |
| internal long position = - 1; |
| |
| private TermBuffer termBuffer = new TermBuffer(); |
| private TermBuffer prevBuffer = new TermBuffer(); |
| private TermBuffer scanBuffer = new TermBuffer(); // used for scanning |
| |
| private TermInfo termInfo = new TermInfo(); |
| |
| private readonly int format; |
| private readonly bool isIndex = false; |
| internal long indexPointer = 0; |
| internal int indexInterval; |
| internal int skipInterval; |
| internal int maxSkipLevels; |
| private readonly int formatM1SkipInterval; |
| |
| internal SegmentTermEnum(IndexInput i, FieldInfos fis, bool isi) |
| { |
| input = i; |
| fieldInfos = fis; |
| isIndex = isi; |
| maxSkipLevels = 1; // use single-level skip lists for formats > -3 |
| |
| int firstInt = input.ReadInt(); |
| if (firstInt >= 0) |
| { |
| // original-format file, without explicit format version number |
| format = 0; |
| size = firstInt; |
| |
| // back-compatible settings |
| indexInterval = 128; |
| skipInterval = System.Int32.MaxValue; // switch off skipTo optimization |
| } |
| else |
| { |
| // we have a format version number |
| format = firstInt; |
| |
| // check that it is a format we can understand |
| if (format < TermInfosWriter.FORMAT_CURRENT) |
| throw new CorruptIndexException("Unknown format version:" + format + " expected " + TermInfosWriter.FORMAT_CURRENT + " or higher"); |
| |
| size = input.ReadLong(); // read the size |
| |
| if (format == - 1) |
| { |
| if (!isIndex) |
| { |
| indexInterval = input.ReadInt(); |
| formatM1SkipInterval = input.ReadInt(); |
| } |
| // switch off skipTo optimization for file format prior to 1.4rc2 in order to avoid a bug in |
| // skipTo implementation of these versions |
| skipInterval = System.Int32.MaxValue; |
| } |
| else |
| { |
| indexInterval = input.ReadInt(); |
| skipInterval = input.ReadInt(); |
| if (format <= TermInfosWriter.FORMAT) |
| { |
| // this new format introduces multi-level skipping |
| maxSkipLevels = input.ReadInt(); |
| } |
| } |
| System.Diagnostics.Debug.Assert(indexInterval > 0, "indexInterval=" + indexInterval + " is negative; must be > 0"); |
| System.Diagnostics.Debug.Assert(skipInterval > 0, "skipInterval=" + skipInterval + " is negative; must be > 0"); |
| } |
| if (format > TermInfosWriter.FORMAT_VERSION_UTF8_LENGTH_IN_BYTES) |
| { |
| termBuffer.SetPreUTF8Strings(); |
| scanBuffer.SetPreUTF8Strings(); |
| prevBuffer.SetPreUTF8Strings(); |
| } |
| } |
| |
| public System.Object Clone() |
| { |
| SegmentTermEnum clone = null; |
| try |
| { |
| clone = (SegmentTermEnum) base.MemberwiseClone(); |
| } |
| catch (System.Exception) |
| { |
| } |
| |
| clone.input = (IndexInput) input.Clone(); |
| clone.termInfo = new TermInfo(termInfo); |
| |
| clone.termBuffer = (TermBuffer) termBuffer.Clone(); |
| clone.prevBuffer = (TermBuffer) prevBuffer.Clone(); |
| clone.scanBuffer = new TermBuffer(); |
| |
| return clone; |
| } |
| |
| internal void Seek(long pointer, long p, Term t, TermInfo ti) |
| { |
| input.Seek(pointer); |
| position = p; |
| termBuffer.Set(t); |
| prevBuffer.Reset(); |
| termInfo.Set(ti); |
| } |
| |
| /// <summary>Increments the enumeration to the next element. True if one exists.</summary> |
| public override bool Next() |
| { |
| if (position++ >= size - 1) |
| { |
| prevBuffer.Set(termBuffer); |
| termBuffer.Reset(); |
| return false; |
| } |
| |
| prevBuffer.Set(termBuffer); |
| termBuffer.Read(input, fieldInfos); |
| |
| termInfo.docFreq = input.ReadVInt(); // read doc freq |
| termInfo.freqPointer += input.ReadVLong(); // read freq pointer |
| termInfo.proxPointer += input.ReadVLong(); // read prox pointer |
| |
| if (format == - 1) |
| { |
| // just read skipOffset in order to increment file pointer; |
| // value is never used since skipTo is switched off |
| if (!isIndex) |
| { |
| if (termInfo.docFreq > formatM1SkipInterval) |
| { |
| termInfo.skipOffset = input.ReadVInt(); |
| } |
| } |
| } |
| else |
| { |
| if (termInfo.docFreq >= skipInterval) |
| termInfo.skipOffset = input.ReadVInt(); |
| } |
| |
| if (isIndex) |
| indexPointer += input.ReadVLong(); // read index pointer |
| |
| return true; |
| } |
| |
| /// <summary>Optimized scan, without allocating new terms. |
| /// Return number of invocations to next(). |
| /// </summary> |
| internal int ScanTo(Term term) |
| { |
| scanBuffer.Set(term); |
| int count = 0; |
| while (scanBuffer.CompareTo(termBuffer) > 0 && Next()) |
| { |
| count++; |
| } |
| return count; |
| } |
| |
| /// <summary>Returns the current Term in the enumeration. |
| /// Initially invalid, valid after next() called for the first time. |
| /// </summary> |
| public override Term Term |
| { |
| get { return termBuffer.ToTerm(); } |
| } |
| |
| /// <summary>Returns the previous Term enumerated. Initially null.</summary> |
| public /*internal*/ Term Prev() |
| { |
| return prevBuffer.ToTerm(); |
| } |
| |
| /// <summary>Returns the current TermInfo in the enumeration. |
| /// Initially invalid, valid after next() called for the first time. |
| /// </summary> |
| internal TermInfo TermInfo() |
| { |
| return new TermInfo(termInfo); |
| } |
| |
| /// <summary>Sets the argument to the current TermInfo in the enumeration. |
| /// Initially invalid, valid after next() called for the first time. |
| /// </summary> |
| internal void TermInfo(TermInfo ti) |
| { |
| ti.Set(termInfo); |
| } |
| |
| /// <summary>Returns the docFreq from the current TermInfo in the enumeration. |
| /// Initially invalid, valid after next() called for the first time. |
| /// </summary> |
| public override int DocFreq() |
| { |
| return termInfo.docFreq; |
| } |
| |
| /* Returns the freqPointer from the current TermInfo in the enumeration. |
| Initially invalid, valid after next() called for the first time.*/ |
| internal long FreqPointer() |
| { |
| return termInfo.freqPointer; |
| } |
| |
| /* Returns the proxPointer from the current TermInfo in the enumeration. |
| Initially invalid, valid after next() called for the first time.*/ |
| internal long ProxPointer() |
| { |
| return termInfo.proxPointer; |
| } |
| |
| /// <summary>Closes the enumeration to further activity, freeing resources. </summary> |
| protected override void Dispose(bool disposing) |
| { |
| input.Dispose(); |
| } |
| } |
| } |