Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
NumericTokenStream.cs
Go to the documentation of this file.
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 Lucene.Net.Analysis.Tokenattributes;
19 using Lucene.Net.Search;
20 using AttributeSource = Lucene.Net.Util.AttributeSource;
21 using NumericUtils = Lucene.Net.Util.NumericUtils;
22 using NumericField = Lucene.Net.Documents.NumericField;
23 // javadocs
24 
25 namespace Lucene.Net.Analysis
26 {
27 
28  /// <summary> <b>Expert:</b> This class provides a <see cref="TokenStream" />
29  /// for indexing numeric values that can be used by <see cref="NumericRangeQuery{T}" />
30  /// or <see cref="NumericRangeFilter{T}" />.
31  ///
32  /// <p/>Note that for simple usage, <see cref="NumericField" /> is
33  /// recommended. <see cref="NumericField" /> disables norms and
34  /// term freqs, as they are not usually needed during
35  /// searching. If you need to change these settings, you
36  /// should use this class.
37  ///
38  /// <p/>See <see cref="NumericField" /> for capabilities of fields
39  /// indexed numerically.<p/>
40  ///
41  /// <p/>Here's an example usage, for an <c>int</c> field:
42  ///
43  /// <code>
44  /// Field field = new Field(name, new NumericTokenStream(precisionStep).setIntValue(value));
45  /// field.setOmitNorms(true);
46  /// field.setOmitTermFreqAndPositions(true);
47  /// document.add(field);
48  /// </code>
49  ///
50  /// <p/>For optimal performance, re-use the TokenStream and Field instance
51  /// for more than one document:
52  ///
53  /// <code>
54  /// NumericTokenStream stream = new NumericTokenStream(precisionStep);
55  /// Field field = new Field(name, stream);
56  /// field.setOmitNorms(true);
57  /// field.setOmitTermFreqAndPositions(true);
58  /// Document document = new Document();
59  /// document.add(field);
60  ///
61  /// for(all documents) {
62  /// stream.setIntValue(value)
63  /// writer.addDocument(document);
64  /// }
65  /// </code>
66  ///
67  /// <p/>This stream is not intended to be used in analyzers;
68  /// it's more for iterating the different precisions during
69  /// indexing a specific numeric value.<p/>
70  ///
71  /// <p/><b>NOTE</b>: as token streams are only consumed once
72  /// the document is added to the index, if you index more
73  /// than one numeric field, use a separate <c>NumericTokenStream</c>
74  /// instance for each.<p/>
75  ///
76  /// <p/>See <see cref="NumericRangeQuery{T}" /> for more details on the
77  /// <a href="../search/NumericRangeQuery.html#precisionStepDesc"><c>precisionStep</c></a>
78  /// parameter as well as how numeric fields work under the hood.<p/>
79  ///
80  /// <p/><font color="red"><b>NOTE:</b> This API is experimental and
81  /// might change in incompatible ways in the next release.</font>
82  /// Since 2.9
83  /// </summary>
84  public sealed class NumericTokenStream : TokenStream
85  {
86  private void InitBlock()
87  {
88  termAtt = AddAttribute<ITermAttribute>();
89  typeAtt = AddAttribute<ITypeAttribute>();
90  posIncrAtt = AddAttribute<IPositionIncrementAttribute>();
91  }
92 
93  /// <summary>The full precision token gets this token type assigned. </summary>
94  public const System.String TOKEN_TYPE_FULL_PREC = "fullPrecNumeric";
95 
96  /// <summary>The lower precision tokens gets this token type assigned. </summary>
97  public const System.String TOKEN_TYPE_LOWER_PREC = "lowerPrecNumeric";
98 
99  /// <summary> Creates a token stream for numeric values using the default <c>precisionStep</c>
100  /// <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4). The stream is not yet initialized,
101  /// before using set a value using the various set<em>???</em>Value() methods.
102  /// </summary>
103  public NumericTokenStream():this(NumericUtils.PRECISION_STEP_DEFAULT)
104  {
105  }
106 
107  /// <summary> Creates a token stream for numeric values with the specified
108  /// <c>precisionStep</c>. The stream is not yet initialized,
109  /// before using set a value using the various set<em>???</em>Value() methods.
110  /// </summary>
111  public NumericTokenStream(int precisionStep):base()
112  {
113  InitBlock();
114  this.precisionStep = precisionStep;
115  if (precisionStep < 1)
116  throw new System.ArgumentException("precisionStep must be >=1");
117  }
118 
119  /// <summary> Expert: Creates a token stream for numeric values with the specified
120  /// <c>precisionStep</c> using the given <see cref="AttributeSource" />.
121  /// The stream is not yet initialized,
122  /// before using set a value using the various set<em>???</em>Value() methods.
123  /// </summary>
124  public NumericTokenStream(AttributeSource source, int precisionStep):base(source)
125  {
126  InitBlock();
127  this.precisionStep = precisionStep;
128  if (precisionStep < 1)
129  throw new System.ArgumentException("precisionStep must be >=1");
130  }
131 
132  /// <summary> Expert: Creates a token stream for numeric values with the specified
133  /// <c>precisionStep</c> using the given
134  /// <see cref="Lucene.Net.Util.AttributeSource.AttributeFactory" />.
135  /// The stream is not yet initialized,
136  /// before using set a value using the various set<em>???</em>Value() methods.
137  /// </summary>
138  public NumericTokenStream(AttributeFactory factory, int precisionStep):base(factory)
139  {
140  InitBlock();
141  this.precisionStep = precisionStep;
142  if (precisionStep < 1)
143  throw new System.ArgumentException("precisionStep must be >=1");
144  }
145 
146  /// <summary> Initializes the token stream with the supplied <c>long</c> value.</summary>
147  /// <param name="value_Renamed">the value, for which this TokenStream should enumerate tokens.
148  /// </param>
149  /// <returns> this instance, because of this you can use it the following way:
150  /// <c>new Field(name, new NumericTokenStream(precisionStep).SetLongValue(value))</c>
151  /// </returns>
152  public NumericTokenStream SetLongValue(long value_Renamed)
153  {
154  this.value_Renamed = value_Renamed;
155  valSize = 64;
156  shift = 0;
157  return this;
158  }
159 
160  /// <summary> Initializes the token stream with the supplied <c>int</c> value.</summary>
161  /// <param name="value_Renamed">the value, for which this TokenStream should enumerate tokens.
162  /// </param>
163  /// <returns> this instance, because of this you can use it the following way:
164  /// <c>new Field(name, new NumericTokenStream(precisionStep).SetIntValue(value))</c>
165  /// </returns>
166  public NumericTokenStream SetIntValue(int value_Renamed)
167  {
168  this.value_Renamed = (long) value_Renamed;
169  valSize = 32;
170  shift = 0;
171  return this;
172  }
173 
174  /// <summary> Initializes the token stream with the supplied <c>double</c> value.</summary>
175  /// <param name="value_Renamed">the value, for which this TokenStream should enumerate tokens.
176  /// </param>
177  /// <returns> this instance, because of this you can use it the following way:
178  /// <c>new Field(name, new NumericTokenStream(precisionStep).SetDoubleValue(value))</c>
179  /// </returns>
180  public NumericTokenStream SetDoubleValue(double value_Renamed)
181  {
182  this.value_Renamed = NumericUtils.DoubleToSortableLong(value_Renamed);
183  valSize = 64;
184  shift = 0;
185  return this;
186  }
187 
188  /// <summary> Initializes the token stream with the supplied <c>float</c> value.</summary>
189  /// <param name="value_Renamed">the value, for which this TokenStream should enumerate tokens.
190  /// </param>
191  /// <returns> this instance, because of this you can use it the following way:
192  /// <c>new Field(name, new NumericTokenStream(precisionStep).SetFloatValue(value))</c>
193  /// </returns>
194  public NumericTokenStream SetFloatValue(float value_Renamed)
195  {
196  this.value_Renamed = (long) NumericUtils.FloatToSortableInt(value_Renamed);
197  valSize = 32;
198  shift = 0;
199  return this;
200  }
201 
202  // @Override
203  public override void Reset()
204  {
205  if (valSize == 0)
206  throw new System.SystemException("call set???Value() before usage");
207  shift = 0;
208  }
209 
210  protected override void Dispose(bool disposing)
211  {
212  // Do nothing.
213  }
214 
215  // @Override
216  public override bool IncrementToken()
217  {
218  if (valSize == 0)
219  throw new System.SystemException("call set???Value() before usage");
220  if (shift >= valSize)
221  return false;
222 
223  ClearAttributes();
224  char[] buffer;
225  switch (valSize)
226  {
227 
228  case 64:
229  buffer = termAtt.ResizeTermBuffer(NumericUtils.BUF_SIZE_LONG);
230  termAtt.SetTermLength(NumericUtils.LongToPrefixCoded(value_Renamed, shift, buffer));
231  break;
232 
233 
234  case 32:
235  buffer = termAtt.ResizeTermBuffer(NumericUtils.BUF_SIZE_INT);
236  termAtt.SetTermLength(NumericUtils.IntToPrefixCoded((int) value_Renamed, shift, buffer));
237  break;
238 
239 
240  default:
241  // should not happen
242  throw new System.ArgumentException("valSize must be 32 or 64");
243 
244  }
245 
246  typeAtt.Type = (shift == 0)?TOKEN_TYPE_FULL_PREC:TOKEN_TYPE_LOWER_PREC;
247  posIncrAtt.PositionIncrement = (shift == 0)?1:0;
248  shift += precisionStep;
249  return true;
250  }
251 
252  // @Override
253  public override System.String ToString()
254  {
255  System.Text.StringBuilder sb = new System.Text.StringBuilder("(numeric,valSize=").Append(valSize);
256  sb.Append(",precisionStep=").Append(precisionStep).Append(')');
257  return sb.ToString();
258  }
259 
260  // members
261  private ITermAttribute termAtt;
262  private ITypeAttribute typeAtt;
263  private IPositionIncrementAttribute posIncrAtt;
264 
265  private int shift = 0, valSize = 0; // valSize==0 means not initialized
266  private readonly int precisionStep;
267 
268  private long value_Renamed = 0L;
269  }
270 }