/* * 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); } /// Increments the enumeration to the next element. True if one exists. 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; } /// Optimized scan, without allocating new terms. /// Return number of invocations to next(). /// internal int ScanTo(Term term) { scanBuffer.Set(term); int count = 0; while (scanBuffer.CompareTo(termBuffer) > 0 && Next()) { count++; } return count; } /// Returns the current Term in the enumeration. /// Initially invalid, valid after next() called for the first time. /// public override Term Term { get { return termBuffer.ToTerm(); } } /// Returns the previous Term enumerated. Initially null. public /*internal*/ Term Prev() { return prevBuffer.ToTerm(); } /// Returns the current TermInfo in the enumeration. /// Initially invalid, valid after next() called for the first time. /// internal TermInfo TermInfo() { return new TermInfo(termInfo); } /// Sets the argument to the current TermInfo in the enumeration. /// Initially invalid, valid after next() called for the first time. /// internal void TermInfo(TermInfo ti) { ti.Set(termInfo); } /// Returns the docFreq from the current TermInfo in the enumeration. /// Initially invalid, valid after next() called for the first time. /// 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; } /// Closes the enumeration to further activity, freeing resources. protected override void Dispose(bool disposing) { input.Dispose(); } } }