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
FieldDocSortedHitQueue.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 Lucene.Net.Util;
20 
21 namespace Lucene.Net.Search
22 {
23 
33  {
34  internal volatile SortField[] fields = null;
35 
36  // used in the case where the fields are sorted by locale
37  // based strings
38  internal volatile System.Globalization.CompareInfo[] collators;
39 
40 
43  internal FieldDocSortedHitQueue(int size)
44  {
45  Initialize(size);
46  }
47 
48 
56  internal virtual void SetFields(SortField[] fields)
57  {
58  lock (this)
59  {
60  this.fields = fields;
61  this.collators = HasCollators(fields);
62  }
63  }
64 
66  internal virtual SortField[] GetFields()
67  {
68  return fields;
69  }
70 
71 
77  private System.Globalization.CompareInfo[] HasCollators(SortField[] fields)
78  {
79  if (fields == null)
80  return null;
81  System.Globalization.CompareInfo[] ret = new System.Globalization.CompareInfo[fields.Length];
82  for (int i = 0; i < fields.Length; ++i)
83  {
84  System.Globalization.CultureInfo locale = fields[i].Locale;
85  if (locale != null)
86  ret[i] = locale.CompareInfo;
87  }
88  return ret;
89  }
90 
91 
96  public override bool LessThan(FieldDoc docA, FieldDoc docB)
97  {
98  int n = fields.Length;
99  int c = 0;
100  for (int i = 0; i < n && c == 0; ++i)
101  {
102  int type = fields[i].Type;
103  if(type == SortField.STRING)
104  {
105  string s1 = (string) docA.fields[i];
106  string s2 = (string) docB.fields[i];
107  // null values need to be sorted first, because of how FieldCache.getStringIndex()
108  // works - in that routine, any documents without a value in the given field are
109  // put first. If both are null, the next SortField is used
110  if (s1 == null)
111  {
112  c = (s2 == null) ? 0 : -1;
113  }
114  else if (s2 == null)
115  {
116  c = 1;
117  }
118  else if (fields[i].Locale == null)
119  {
120  c = s1.CompareTo(s2);
121  }
122  else
123  {
124  c = collators[i].Compare(s1, s2);
125  }
126  }
127  else
128  {
129  c = docA.fields[i].CompareTo(docB.fields[i]);
130  if (type == SortField.SCORE)
131  {
132  c = -c;
133  }
134  }
135  if (fields[i].Reverse)
136  {
137  c = - c;
138  }
139  }
140 
141  // avoid random sort order that could lead to duplicates (bug #31241):
142  if (c == 0)
143  return docA.Doc > docB.Doc;
144 
145  return c > 0;
146  }
147  }
148 }