FileDocCategorySizeDatePackage
FieldDocSortedHitQueue.javaAPI DocApache Lucene 2.1.05627Wed Feb 14 10:46:38 GMT 2007org.apache.lucene.search

FieldDocSortedHitQueue

public class FieldDocSortedHitQueue extends PriorityQueue
Expert: Collects sorted results from Searchable's and collates them. The elements put into this queue must be of type FieldDoc.

Created: Feb 11, 2004 2:04:21 PM

author
Tim Jones (Nacimiento Software)
since
lucene 1.4
version
$Id: FieldDocSortedHitQueue.java 472959 2006-11-09 16:21:50Z yonik $

Fields Summary
volatile SortField[]
fields
volatile Collator[]
collators
Constructors Summary
FieldDocSortedHitQueue(SortField[] fields, int size)
Creates a hit queue sorted by the given list of fields.

param
fields Fieldable names, in priority order (highest priority first).
param
size The number of hits to retain. Must be greater than zero.

		this.fields = fields;
		this.collators = hasCollators (fields);
		initialize (size);
	
Methods Summary
org.apache.lucene.search.SortField[]getFields()
Returns the fields being used to sort.

		return fields;
	
private java.text.Collator[]hasCollators(org.apache.lucene.search.SortField[] fields)
Returns an array of collators, possibly null. The collators correspond to any SortFields which were given a specific locale.

param
fields Array of sort fields.
return
Array, possibly null.

		if (fields == null) return null;
		Collator[] ret = new Collator[fields.length];
		for (int i=0; i<fields.length; ++i) {
			Locale locale = fields[i].getLocale();
			if (locale != null)
				ret[i] = Collator.getInstance (locale);
		}
		return ret;
	
protected final booleanlessThan(java.lang.Object a, java.lang.Object b)
Returns whether a is less relevant than b.

param
a ScoreDoc
param
b ScoreDoc
return
true if document a should be sorted after document b.

		final FieldDoc docA = (FieldDoc) a;
		final FieldDoc docB = (FieldDoc) b;
		final int n = fields.length;
		int c = 0;
		for (int i=0; i<n && c==0; ++i) {
			final int type = fields[i].getType();
			switch (type) {
				case SortField.SCORE:
					float r1 = ((Float)docA.fields[i]).floatValue();
					float r2 = ((Float)docB.fields[i]).floatValue();
					if (r1 > r2) c = -1;
					if (r1 < r2) c = 1;
					break;
				case SortField.DOC:
				case SortField.INT:
					int i1 = ((Integer)docA.fields[i]).intValue();
					int i2 = ((Integer)docB.fields[i]).intValue();
					if (i1 < i2) c = -1;
					if (i1 > i2) c = 1;
					break;
				case SortField.STRING:
					String s1 = (String) docA.fields[i];
					String s2 = (String) docB.fields[i];
					// null values need to be sorted first, because of how FieldCache.getStringIndex()
					// works - in that routine, any documents without a value in the given field are
					// put first.  If both are null, the next SortField is used
					if (s1 == null) c = (s2==null) ? 0 : -1;
					else if (s2 == null) c = 1;  // 
					else if (fields[i].getLocale() == null) {
						c = s1.compareTo(s2);
					} else {
						c = collators[i].compare (s1, s2);
					}
					break;
				case SortField.FLOAT:
					float f1 = ((Float)docA.fields[i]).floatValue();
					float f2 = ((Float)docB.fields[i]).floatValue();
					if (f1 < f2) c = -1;
					if (f1 > f2) c = 1;
					break;
				case SortField.CUSTOM:
					c = docA.fields[i].compareTo (docB.fields[i]);
					break;
				case SortField.AUTO:
					// we cannot handle this - even if we determine the type of object (Float or
					// Integer), we don't necessarily know how to compare them (both SCORE and
					// FLOAT contain floats, but are sorted opposite of each other). Before
					// we get here, each AUTO should have been replaced with its actual value.
					throw new RuntimeException ("FieldDocSortedHitQueue cannot use an AUTO SortField");
				default:
					throw new RuntimeException ("invalid SortField type: "+type);
			}
			if (fields[i].getReverse()) {
				c = -c;
			}
		}

    // avoid random sort order that could lead to duplicates (bug #31241):
    if (c == 0)
      return docA.doc > docB.doc;

    return c > 0;
	
synchronized voidsetFields(org.apache.lucene.search.SortField[] fields)
Allows redefinition of sort fields if they are null. This is to handle the case using ParallelMultiSearcher where the original list contains AUTO and we don't know the actual sort type until the values come back. The fields can only be set once. This method is thread safe.

param
fields

		if (this.fields == null) {
			this.fields = fields;
			this.collators = hasCollators (fields);
		}