/* * 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 System; using AttributeSource = Lucene.Net.Util.AttributeSource; using NumericUtils = Lucene.Net.Util.NumericUtils; using NumericField = Lucene.Net.Documents.NumericField; // for javadocs using NumericRangeQuery = Lucene.Net.Search.NumericRangeQuery; using NumericRangeFilter = Lucene.Net.Search.NumericRangeFilter; using SortField = Lucene.Net.Search.SortField; using FieldCache = Lucene.Net.Search.FieldCache; // javadocs using TermAttribute = Lucene.Net.Analysis.Tokenattributes.TermAttribute; using TypeAttribute = Lucene.Net.Analysis.Tokenattributes.TypeAttribute; using PositionIncrementAttribute = Lucene.Net.Analysis.Tokenattributes.PositionIncrementAttribute; namespace Lucene.Net.Analysis { /// Expert: This class provides a {@link TokenStream} /// for indexing numeric values that can be used by {@link /// NumericRangeQuery} or {@link NumericRangeFilter}. /// ///

Note that for simple usage, {@link NumericField} is /// recommended. {@link NumericField} disables norms and /// term freqs, as they are not usually needed during /// searching. If you need to change these settings, you /// should use this class. /// ///

See {@link NumericField} for capabilities of fields /// indexed numerically.

/// ///

Here's an example usage, for an int field: /// ///

	///  Field field = new Field(name, new NumericTokenStream(precisionStep).setIntValue(value));
	///  field.setOmitNorms(true);
	///  field.setOmitTermFreqAndPositions(true);
	///  document.add(field);
	/// 
/// ///

For optimal performance, re-use the TokenStream and Field instance /// for more than one document: /// ///

	///  NumericTokenStream stream = new NumericTokenStream(precisionStep);
	///  Field field = new Field(name, stream);
	///  field.setOmitNorms(true);
	///  field.setOmitTermFreqAndPositions(true);
	///  Document document = new Document();
	///  document.add(field);
	/// 
	///  for(all documents) {
	///    stream.setIntValue(value)
	///    writer.addDocument(document);
	///  }
	/// 
/// ///

This stream is not intended to be used in analyzers; /// it's more for iterating the different precisions during /// indexing a specific numeric value.

/// ///

NOTE: as token streams are only consumed once /// the document is added to the index, if you index more /// than one numeric field, use a separate NumericTokenStream /// instance for each.

/// ///

See {@link NumericRangeQuery} for more details on the /// precisionStep /// parameter as well as how numeric fields work under the hood.

/// ///

NOTE: This API is experimental and /// might change in incompatible ways in the next release. /// ///

/// 2.9 /// public sealed class NumericTokenStream:TokenStream { private void InitBlock() { termAtt = (TermAttribute) AddAttribute(typeof(TermAttribute)); typeAtt = (TypeAttribute) AddAttribute(typeof(TypeAttribute)); posIncrAtt = (PositionIncrementAttribute) AddAttribute(typeof(PositionIncrementAttribute)); } /// The full precision token gets this token type assigned. public const System.String TOKEN_TYPE_FULL_PREC = "fullPrecNumeric"; /// The lower precision tokens gets this token type assigned. public const System.String TOKEN_TYPE_LOWER_PREC = "lowerPrecNumeric"; /// Creates a token stream for numeric values using the default precisionStep /// {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). The stream is not yet initialized, /// before using set a value using the various set???Value() methods. /// public NumericTokenStream():this(NumericUtils.PRECISION_STEP_DEFAULT) { } /// Creates a token stream for numeric values with the specified /// precisionStep. The stream is not yet initialized, /// before using set a value using the various set???Value() methods. /// public NumericTokenStream(int precisionStep):base() { InitBlock(); this.precisionStep = precisionStep; if (precisionStep < 1) throw new System.ArgumentException("precisionStep must be >=1"); } /// Expert: Creates a token stream for numeric values with the specified /// precisionStep using the given {@link AttributeSource}. /// The stream is not yet initialized, /// before using set a value using the various set???Value() methods. /// public NumericTokenStream(AttributeSource source, int precisionStep):base(source) { InitBlock(); this.precisionStep = precisionStep; if (precisionStep < 1) throw new System.ArgumentException("precisionStep must be >=1"); } /// Expert: Creates a token stream for numeric values with the specified /// precisionStep using the given /// {@link org.apache.lucene.util.AttributeSource.AttributeFactory}. /// The stream is not yet initialized, /// before using set a value using the various set???Value() methods. /// public NumericTokenStream(AttributeFactory factory, int precisionStep):base(factory) { InitBlock(); this.precisionStep = precisionStep; if (precisionStep < 1) throw new System.ArgumentException("precisionStep must be >=1"); } /// Initializes the token stream with the supplied long value. /// the value, for which this TokenStream should enumerate tokens. /// /// this instance, because of this you can use it the following way: /// new Field(name, new NumericTokenStream(precisionStep).SetLongValue(value)) /// public NumericTokenStream SetLongValue(long value_Renamed) { this.value_Renamed = value_Renamed; valSize = 64; shift = 0; return this; } /// Initializes the token stream with the supplied int value. /// the value, for which this TokenStream should enumerate tokens. /// /// this instance, because of this you can use it the following way: /// new Field(name, new NumericTokenStream(precisionStep).SetIntValue(value)) /// public NumericTokenStream SetIntValue(int value_Renamed) { this.value_Renamed = (long) value_Renamed; valSize = 32; shift = 0; return this; } /// Initializes the token stream with the supplied double value. /// the value, for which this TokenStream should enumerate tokens. /// /// this instance, because of this you can use it the following way: /// new Field(name, new NumericTokenStream(precisionStep).SetDoubleValue(value)) /// public NumericTokenStream SetDoubleValue(double value_Renamed) { this.value_Renamed = NumericUtils.DoubleToSortableLong(value_Renamed); valSize = 64; shift = 0; return this; } /// Initializes the token stream with the supplied float value. /// the value, for which this TokenStream should enumerate tokens. /// /// this instance, because of this you can use it the following way: /// new Field(name, new NumericTokenStream(precisionStep).SetFloatValue(value)) /// public NumericTokenStream SetFloatValue(float value_Renamed) { this.value_Renamed = (long) NumericUtils.FloatToSortableInt(value_Renamed); valSize = 32; shift = 0; return this; } // @Override public override void Reset() { if (valSize == 0) throw new System.SystemException("call set???Value() before usage"); shift = 0; } // @Override public override bool IncrementToken() { if (valSize == 0) throw new System.SystemException("call set???Value() before usage"); if (shift >= valSize) return false; ClearAttributes(); char[] buffer; switch (valSize) { case 64: buffer = termAtt.ResizeTermBuffer(NumericUtils.BUF_SIZE_LONG); termAtt.SetTermLength(NumericUtils.LongToPrefixCoded(value_Renamed, shift, buffer)); break; case 32: buffer = termAtt.ResizeTermBuffer(NumericUtils.BUF_SIZE_INT); termAtt.SetTermLength(NumericUtils.IntToPrefixCoded((int) value_Renamed, shift, buffer)); break; default: // should not happen throw new System.ArgumentException("valSize must be 32 or 64"); } typeAtt.SetType((shift == 0)?TOKEN_TYPE_FULL_PREC:TOKEN_TYPE_LOWER_PREC); posIncrAtt.SetPositionIncrement((shift == 0)?1:0); shift += precisionStep; return true; } // @Override public override System.String ToString() { System.Text.StringBuilder sb = new System.Text.StringBuilder("(numeric,valSize=").Append(valSize); sb.Append(",precisionStep=").Append(precisionStep).Append(')'); return sb.ToString(); } // members private TermAttribute termAtt; private TypeAttribute typeAtt; private PositionIncrementAttribute posIncrAtt; private int shift = 0, valSize = 0; // valSize==0 means not initialized private int precisionStep; private long value_Renamed = 0L; } }