/* * 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.Util; namespace Lucene.Net.Search { /// 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 /// ///

/// lucene 1.4 /// class FieldDocSortedHitQueue : PriorityQueue { internal volatile SortField[] fields = null; // used in the case where the fields are sorted by locale // based strings internal volatile System.Globalization.CompareInfo[] collators; /// Creates a hit queue sorted by the given list of fields. /// The number of hits to retain. Must be greater than zero. internal FieldDocSortedHitQueue(int size) { Initialize(size); } /// 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. /// /// internal virtual void SetFields(SortField[] fields) { lock (this) { this.fields = fields; this.collators = HasCollators(fields); } } /// Returns the fields being used to sort. internal virtual SortField[] GetFields() { return fields; } /// Returns an array of collators, possibly null. The collators /// correspond to any SortFields which were given a specific locale. /// /// Array of sort fields. /// Array, possibly null. private System.Globalization.CompareInfo[] HasCollators(SortField[] fields) { if (fields == null) return null; System.Globalization.CompareInfo[] ret = new System.Globalization.CompareInfo[fields.Length]; for (int i = 0; i < fields.Length; ++i) { System.Globalization.CultureInfo locale = fields[i].Locale; if (locale != null) ret[i] = locale.CompareInfo; } return ret; } /// Returns whether a is less relevant than b. /// ScoreDoc /// ScoreDoc /// true if document a should be sorted after document b. public override bool LessThan(FieldDoc docA, FieldDoc docB) { int n = fields.Length; int c = 0; for (int i = 0; i < n && c == 0; ++i) { int type = fields[i].Type; if(type == 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].Locale == null) { c = s1.CompareTo(s2); } else { c = collators[i].Compare(s1, s2); } } else { c = docA.fields[i].CompareTo(docB.fields[i]); if (type == SortField.SCORE) { c = -c; } } if (fields[i].Reverse) { c = - c; } } // avoid random sort order that could lead to duplicates (bug #31241): if (c == 0) return docA.Doc > docB.Doc; return c > 0; } } }