Lucene.Net  3.0.3
Lucene.Net is a .NET port of the Java Lucene Indexing Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties
SortField.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 System;
19 using System.Globalization;
20 using Lucene.Net.Support;
21 using NumericField = Lucene.Net.Documents.NumericField;
22 using IndexReader = Lucene.Net.Index.IndexReader;
23 using Single = Lucene.Net.Support.Single;
24 using Term = Lucene.Net.Index.Term;
25 using TermEnum = Lucene.Net.Index.TermEnum;
26 using StringHelper = Lucene.Net.Util.StringHelper;
27 
28 namespace Lucene.Net.Search
29 {
30 
37  [Serializable]
38  public class SortField
39  {
43  public const int SCORE = 0;
44 
48  public const int DOC = 1;
49 
50  // reserved, in Lucene 2.9, there was a constant: AUTO = 2
51 
55  public const int STRING = 3;
56 
60  public const int INT = 4;
61 
65  public const int FLOAT = 5;
66 
70  public const int LONG = 6;
71 
75  public const int DOUBLE = 7;
76 
80  public const int SHORT = 8;
81 
85  public const int CUSTOM = 9;
86 
90  public const int BYTE = 10;
91 
97  public const int STRING_VAL = 11;
98 
99  // IMPLEMENTATION NOTE: the FieldCache.STRING_INDEX is in the same "namespace"
100  // as the above static int values. Any new values must not have the same value
101  // as FieldCache.STRING_INDEX.
102 
104  public static readonly SortField FIELD_SCORE = new SortField(null, SCORE);
105 
107  public static readonly SortField FIELD_DOC = new SortField(null, DOC);
108 
109  private System.String field;
110  private int type; // defaults to determining type dynamically
111  private System.Globalization.CultureInfo locale; // defaults to "natural order" (no Locale)
112  internal bool reverse = false; // defaults to natural order
113  private Lucene.Net.Search.Parser parser;
114 
115  // Used for CUSTOM sort
116  private FieldComparatorSource comparatorSource;
117 
126  public SortField(System.String field, int type)
127  {
128  InitFieldType(field, type);
129  }
130 
141  public SortField(System.String field, int type, bool reverse)
142  {
143  InitFieldType(field, type);
144  this.reverse = reverse;
145  }
146 
160  public SortField(System.String field, Lucene.Net.Search.Parser parser):this(field, parser, false)
161  {
162  }
163 
179  public SortField(System.String field, Lucene.Net.Search.Parser parser, bool reverse)
180  {
181  if (parser is Lucene.Net.Search.IntParser)
182  InitFieldType(field, INT);
183  else if (parser is Lucene.Net.Search.FloatParser)
184  InitFieldType(field, FLOAT);
185  else if (parser is Lucene.Net.Search.ShortParser)
186  InitFieldType(field, SHORT);
187  else if (parser is Lucene.Net.Search.ByteParser)
188  InitFieldType(field, BYTE);
189  else if (parser is Lucene.Net.Search.LongParser)
190  InitFieldType(field, LONG);
191  else if (parser is Lucene.Net.Search.DoubleParser)
192  InitFieldType(field, DOUBLE);
193  else
194  {
195  throw new System.ArgumentException("Parser instance does not subclass existing numeric parser from FieldCache (got " + parser + ")");
196  }
197 
198  this.reverse = reverse;
199  this.parser = parser;
200  }
201 
209  public SortField(System.String field, System.Globalization.CultureInfo locale)
210  {
211  InitFieldType(field, STRING);
212  this.locale = locale;
213  }
214 
222  public SortField(System.String field, System.Globalization.CultureInfo locale, bool reverse)
223  {
224  InitFieldType(field, STRING);
225  this.locale = locale;
226  this.reverse = reverse;
227  }
228 
234  public SortField(System.String field, FieldComparatorSource comparator)
235  {
236  InitFieldType(field, CUSTOM);
237  this.comparatorSource = comparator;
238  }
239 
247  public SortField(System.String field, FieldComparatorSource comparator, bool reverse)
248  {
249  InitFieldType(field, CUSTOM);
250  this.reverse = reverse;
251  this.comparatorSource = comparator;
252  }
253 
254  // Sets field & type, and ensures field is not NULL unless
255  // type is SCORE or DOC
256  private void InitFieldType(System.String field, int type)
257  {
258  this.type = type;
259  if (field == null)
260  {
261  if (type != SCORE && type != DOC)
262  throw new System.ArgumentException("field can only be null when type is SCORE or DOC");
263  }
264  else
265  {
266  this.field = StringHelper.Intern(field);
267  }
268  }
269 
274  public virtual string Field
275  {
276  get { return field; }
277  }
278 
281  public virtual int Type
282  {
283  get { return type; }
284  }
285 
290  public virtual CultureInfo Locale
291  {
292  get { return locale; }
293  }
294 
299  public virtual Parser Parser
300  {
301  get { return parser; }
302  }
303 
306  public virtual bool Reverse
307  {
308  get { return reverse; }
309  }
310 
315  public virtual FieldComparatorSource ComparatorSource
316  {
317  get { return comparatorSource; }
318  }
319 
320  public override System.String ToString()
321  {
322  System.Text.StringBuilder buffer = new System.Text.StringBuilder();
323  switch (type)
324  {
325 
326  case SCORE:
327  buffer.Append("<score>");
328  break;
329 
330  case DOC:
331  buffer.Append("<doc>");
332  break;
333 
334  case STRING:
335  buffer.Append("<string: \"").Append(field).Append("\">");
336  break;
337 
338  case STRING_VAL:
339  buffer.Append("<string_val: \"").Append(field).Append("\">");
340  break;
341 
342  case BYTE:
343  buffer.Append("<byte: \"").Append(field).Append("\">");
344  break;
345 
346  case SHORT:
347  buffer.Append("<short: \"").Append(field).Append("\">");
348  break;
349 
350  case INT:
351  buffer.Append("<int: \"").Append(field).Append("\">");
352  break;
353 
354  case LONG:
355  buffer.Append("<long: \"").Append(field).Append("\">");
356  break;
357 
358  case FLOAT:
359  buffer.Append("<float: \"").Append(field).Append("\">");
360  break;
361 
362  case DOUBLE:
363  buffer.Append("<double: \"").Append(field).Append("\">");
364  break;
365 
366  case CUSTOM:
367  buffer.Append("<custom:\"").Append(field).Append("\": ").Append(comparatorSource).Append('>');
368  break;
369 
370  default:
371  buffer.Append("<???: \"").Append(field).Append("\">");
372  break;
373 
374  }
375 
376  if (locale != null)
377  buffer.Append('(').Append(locale).Append(')');
378  if (parser != null)
379  buffer.Append('(').Append(parser).Append(')');
380  if (reverse)
381  buffer.Append('!');
382 
383  return buffer.ToString();
384  }
385 
391  public override bool Equals(System.Object o)
392  {
393  if (this == o)
394  return true;
395  if (!(o is SortField))
396  return false;
397  SortField other = (SortField) o;
398  return ((System.Object) other.field == (System.Object) this.field && other.type == this.type &&
399  other.reverse == this.reverse &&
400  (other.locale == null ? this.locale == null : other.locale.Equals(this.locale)) &&
401  (other.comparatorSource == null
402  ? this.comparatorSource == null
403  : other.comparatorSource.Equals(this.comparatorSource)) &&
404  (other.parser == null ? this.parser == null : other.parser.Equals(this.parser)));
405  }
406 
413  public override int GetHashCode()
414  {
415  int hash = type ^ 0x346565dd + (reverse ? Boolean.TrueString.GetHashCode() : Boolean.FalseString.GetHashCode()) ^ unchecked((int) 0xaf5998bb);
416  if (field != null)
417  hash += (field.GetHashCode() ^ unchecked((int) 0xff5685dd));
418  if (locale != null)
419  {
420  hash += (locale.GetHashCode() ^ 0x08150815);
421  }
422  if (comparatorSource != null)
423  hash += comparatorSource.GetHashCode();
424  if (parser != null)
425  hash += (parser.GetHashCode() ^ 0x3aaf56ff);
426  return hash;
427  }
428 
429 
431  // private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
432  // in.defaultReadObject();
433  // if (field != null)
434  // field = StringHelper.intern(field);
435  // }
436 
437  [System.Runtime.Serialization.OnDeserialized]
438  internal void OnDeserialized(System.Runtime.Serialization.StreamingContext context)
439  {
440  field = StringHelper.Intern(field);
441  }
442 
459  public virtual FieldComparator GetComparator(int numHits, int sortPos)
460  {
461 
462  if (locale != null)
463  {
464  // TODO: it'd be nice to allow FieldCache.getStringIndex
465  // to optionally accept a Locale so sorting could then use
466  // the faster StringComparator impls
467  return new FieldComparator.StringComparatorLocale(numHits, field, locale);
468  }
469 
470  switch (type)
471  {
472  case SortField.SCORE:
473  return new FieldComparator.RelevanceComparator(numHits);
474 
475  case SortField.DOC:
476  return new FieldComparator.DocComparator(numHits);
477 
478  case SortField.INT:
479  return new FieldComparator.IntComparator(numHits, field, parser);
480 
481  case SortField.FLOAT:
482  return new FieldComparator.FloatComparator(numHits, field, parser);
483 
484  case SortField.LONG:
485  return new FieldComparator.LongComparator(numHits, field, parser);
486 
487  case SortField.DOUBLE:
488  return new FieldComparator.DoubleComparator(numHits, field, parser);
489 
490  case SortField.BYTE:
491  return new FieldComparator.ByteComparator(numHits, field, parser);
492 
493  case SortField.SHORT:
494  return new FieldComparator.ShortComparator(numHits, field, parser);
495 
496  case SortField.CUSTOM:
497  System.Diagnostics.Debug.Assert(comparatorSource != null);
498  return comparatorSource.NewComparator(field, numHits, sortPos, reverse);
499 
500  case SortField.STRING:
501  return new FieldComparator.StringOrdValComparator(numHits, field, sortPos, reverse);
502 
503  case SortField.STRING_VAL:
504  return new FieldComparator.StringValComparator(numHits, field);
505 
506  default:
507  throw new System.SystemException("Illegal sort type: " + type);
508 
509  }
510  }
511  }
512 }