/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed 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 System;
using InputStream = Lucene.Net.Store.InputStream;
namespace Lucene.Net.Index
{
sealed public class SegmentTermEnum:TermEnum, System.ICloneable
{
private InputStream input;
internal FieldInfos fieldInfos;
internal long size;
internal long position = - 1;
private Term term = new Term("", "");
private TermInfo termInfo = new TermInfo();
private int format;
private bool isIndex = false;
internal long indexPointer = 0;
internal int indexInterval;
internal int skipInterval;
private int formatM1SkipInterval;
internal Term prev;
private char[] buffer = new char[]{};
internal SegmentTermEnum(InputStream i, FieldInfos fis, bool isi)
{
input = i;
fieldInfos = fis;
isIndex = isi;
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)
throw new System.IO.IOException("Unknown format version:" + format);
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();
}
}
}
public System.Object Clone()
{
SegmentTermEnum clone = null;
try
{
clone = (SegmentTermEnum) base.MemberwiseClone();
}
catch (System.Exception)
{
}
clone.input = (InputStream) input.Clone();
clone.termInfo = new TermInfo(termInfo);
if (term != null)
clone.GrowBuffer(term.text.Length);
return clone;
}
internal void Seek(long pointer, int p, Term t, TermInfo ti)
{
input.Seek(pointer);
position = p;
term = t;
prev = null;
termInfo.Set(ti);
GrowBuffer(term.text.Length); // copy term text into buffer
}
/// Increments the enumeration to the next element. True if one exists.
public override bool Next()
{
if (position++ >= size - 1)
{
term = null;
return false;
}
prev = term;
term = ReadTerm();
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;
}
private Term ReadTerm()
{
int start = input.ReadVInt();
int length = input.ReadVInt();
int totalLength = start + length;
if (buffer.Length < totalLength)
GrowBuffer(totalLength);
input.ReadChars(buffer, start, length);
return new Term(fieldInfos.FieldName(input.ReadVInt()), new System.String(buffer, 0, totalLength), false);
}
private void GrowBuffer(int length)
{
buffer = new char[length];
for (int i = 0; i < term.text.Length; i++)
// copy contents
buffer[i] = term.text[i];
}
/// Returns the current Term in the enumeration.
/// Initially invalid, valid after next() called for the first time.
///
public override Term Term()
{
return term;
}
/// Returns the current TermInfo in the enumeration.
/// Initially invalid, valid after next() called for the first time.
///
public /*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.
public override void Close()
{
input.Close();
}
}
}