/*
* 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 Lucene.Net.Support;
namespace Lucene.Net.Search
{
/// Encapsulates sort criteria for returned hits.
///
/// The fields used to determine sort order must be carefully chosen.
/// Documents must contain a single term in such a field,
/// and the value of the term should indicate the document's relative position in
/// a given sort order. The field must be indexed, but should not be tokenized,
/// and does not need to be stored (unless you happen to want it back with the
/// rest of your document data). In other words:
///
/// document.add (new Field ("byNumber", Integer.toString(x), Field.Store.NO, Field.Index.NOT_ANALYZED));
///
///
/// Valid Types of Values
///
/// There are four possible kinds of term values which may be put into
/// sorting fields: Integers, Longs, Floats, or Strings. Unless
/// SortField objects are specified, the type of value
/// in the field is determined by parsing the first term in the field.
///
/// Integer term values should contain only digits and an optional
/// preceding negative sign. Values must be base 10 and in the range
/// Integer.MIN_VALUE and Integer.MAX_VALUE inclusive.
/// Documents which should appear first in the sort
/// should have low value integers, later documents high values
/// (i.e. the documents should be numbered 1..n where
/// 1 is the first and n the last).
///
/// Long term values should contain only digits and an optional
/// preceding negative sign. Values must be base 10 and in the range
/// Long.MIN_VALUE and Long.MAX_VALUE inclusive.
/// Documents which should appear first in the sort
/// should have low value integers, later documents high values.
///
/// Float term values should conform to values accepted by
/// (except that NaN
/// and Infinity are not supported).
/// Documents which should appear first in the sort
/// should have low values, later documents high values.
///
/// String term values can contain any valid String, but should
/// not be tokenized. The values are sorted according to their
/// natural order. Note that using this type
/// of term value has higher memory requirements than the other
/// two types.
///
/// Object Reuse
///
/// One of these objects can be
/// used multiple times and the sort order changed between usages.
///
/// This class is thread safe.
///
/// Memory Usage
///
/// Sorting uses of caches of term values maintained by the
/// internal HitQueue(s). The cache is static and contains an integer
/// or float array of length IndexReader.MaxDoc for each field
/// name for which a sort is performed. In other words, the size of the
/// cache in bytes is:
///
/// 4 * IndexReader.MaxDoc * (# of different fields actually used to sort)
///
/// For String fields, the cache is larger: in addition to the
/// above array, the value of every term in the field is kept in memory.
/// If there are many unique terms in the field, this could
/// be quite large.
///
/// Note that the size of the cache is not affected by how many
/// fields are in the index and might be used to sort - only by
/// the ones actually used to sort a result set.
///
/// Created: Feb 12, 2004 10:53:57 AM
///
///
[Serializable]
public class Sort
{
/// Represents sorting by computed relevance. Using this sort criteria returns
/// the same results as calling
/// Searcher#search()without a sort criteria,
/// only with slightly more overhead.
///
public static readonly Sort RELEVANCE = new Sort();
/// Represents sorting by index order.
public static readonly Sort INDEXORDER;
// internal representation of the sort criteria
internal SortField[] fields;
/// Sorts by computed relevance. This is the same sort criteria as calling
/// without a sort criteria,
/// only with slightly more overhead.
///
public Sort():this(SortField.FIELD_SCORE)
{
}
/// Sorts by the criteria in the given SortField.
public Sort(SortField field)
{
SetSort(field);
}
/// Sorts in succession by the criteria in each SortField.
public Sort(params SortField[] fields)
{
SetSort(fields);
}
/// Sets the sort to the given criteria.
public virtual void SetSort(SortField field)
{
this.fields = new SortField[]{field};
}
/// Sets the sort to the given criteria in succession.
public virtual void SetSort(params SortField[] fields)
{
this.fields = fields;
}
/// Representation of the sort criteria.
/// Array of SortField objects used in this sort criteria
///
public virtual SortField[] GetSort()
{
return fields;
}
public override System.String ToString()
{
System.Text.StringBuilder buffer = new System.Text.StringBuilder();
for (int i = 0; i < fields.Length; i++)
{
buffer.Append(fields[i].ToString());
if ((i + 1) < fields.Length)
buffer.Append(',');
}
return buffer.ToString();
}
/// Returns true if o is equal to this.
public override bool Equals(System.Object o)
{
if (this == o)
return true;
if (!(o is Sort))
return false;
Sort other = (Sort) o;
bool result = false;
if ((this.fields == null) && (other.fields == null))
result = true;
else if ((this.fields != null) && (other.fields != null))
{
if (this.fields.Length == other.fields.Length)
{
int length = this.fields.Length;
result = true;
for (int i = 0; i < length; i++)
{
if (!(this.fields[i].Equals(other.fields[i])))
{
result = false;
break;
}
}
}
}
return result;
}
/// Returns a hash code value for this object.
public override int GetHashCode()
{
// TODO in Java 1.5: switch to Arrays.hashCode(). The
// Java 1.4 workaround below calculates the same hashCode
// as Java 1.5's new Arrays.hashCode()
return 0x45aaf665 + EquatableList.GetHashCode(fields);
}
static Sort()
{
INDEXORDER = new Sort(SortField.FIELD_DOC);
}
}
}