Thumbnail file hits. Based on a patch from D Bera
[beagle.git] / beagled / Lucene.Net / Search / MultiSearcher.cs
blob96fe3f699e713c9543b788d34c86a33ceeed3f6a
1 /*
2 * Copyright 2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 using System;
17 using Document = Lucene.Net.Documents.Document;
18 using Term = Lucene.Net.Index.Term;
19 namespace Lucene.Net.Search
22 /// <summary>Implements search over a set of <code>Searchables</code>.
23 ///
24 /// <p>Applications usually need only call the inherited {@link #Search(Query)}
25 /// or {@link #Search(Query,Filter)} methods.
26 /// </summary>
27 public class MultiSearcher : Searcher
29 private class AnonymousClassHitCollector : HitCollector
31 public AnonymousClassHitCollector(Lucene.Net.Search.HitCollector results, int start, MultiSearcher enclosingInstance)
33 InitBlock(results, start, enclosingInstance);
35 private void InitBlock(Lucene.Net.Search.HitCollector results, int start, MultiSearcher enclosingInstance)
37 this.results = results;
38 this.start = start;
39 this.enclosingInstance = enclosingInstance;
41 private Lucene.Net.Search.HitCollector results;
42 private int start;
43 private MultiSearcher enclosingInstance;
44 public MultiSearcher Enclosing_Instance
46 get
48 return enclosingInstance;
52 public override void Collect(int doc, float score)
54 results.Collect(doc + start, score);
57 private Lucene.Net.Search.Searchable[] searchables;
58 private int[] starts;
59 private int maxDoc = 0;
61 /// <summary>Creates a searcher which searches <i>searchables</i>. </summary>
62 public MultiSearcher(Lucene.Net.Search.Searchable[] searchables)
64 this.searchables = searchables;
66 starts = new int[searchables.Length + 1]; // build starts array
67 for (int i = 0; i < searchables.Length; i++)
69 starts[i] = maxDoc;
70 maxDoc += searchables[i].MaxDoc(); // compute maxDocs
72 starts[searchables.Length] = maxDoc;
75 protected internal virtual int[] GetStarts()
77 return starts;
80 // inherit javadoc
81 public override void Close()
83 for (int i = 0; i < searchables.Length; i++)
84 searchables[i].Close();
87 public override int DocFreq(Term term)
89 int docFreq = 0;
90 for (int i = 0; i < searchables.Length; i++)
91 docFreq += searchables[i].DocFreq(term);
92 return docFreq;
95 // inherit javadoc
96 public override Document Doc(int n)
98 int i = SubSearcher(n); // find searcher index
99 return searchables[i].Doc(n - starts[i]); // dispatch to searcher
102 /// <summary>Call {@link #subSearcher} instead.</summary>
103 /// <deprecated>
104 /// </deprecated>
105 public virtual int SearcherIndex(int n)
107 return SubSearcher(n);
110 /// <summary>Returns index of the searcher for document <code>n</code> in the array
111 /// used to construct this searcher.
112 /// </summary>
113 public virtual int SubSearcher(int n)
115 // find searcher for doc n:
116 // replace w/ call to Arrays.binarySearch in Java 1.2
117 int lo = 0; // search starts array
118 int hi = searchables.Length - 1; // for first element less
119 // than n, return its index
120 while (hi >= lo)
122 int mid = (lo + hi) >> 1;
123 int midValue = starts[mid];
124 if (n < midValue)
125 hi = mid - 1;
126 else if (n > midValue)
127 lo = mid + 1;
128 else
130 // found a match
131 while (mid + 1 < searchables.Length && starts[mid + 1] == midValue)
133 mid++; // scan to last match
135 return mid;
138 return hi;
141 /// <summary>Returns the document number of document <code>n</code> within its
142 /// sub-index.
143 /// </summary>
144 public virtual int SubDoc(int n)
146 return n - starts[SubSearcher(n)];
149 public override int MaxDoc()
151 return maxDoc;
154 public override TopDocs Search(Query query, Filter filter, int nDocs)
156 HitQueue hq = new HitQueue(nDocs);
157 int totalHits = 0;
159 for (int i = 0; i < searchables.Length; i++)
161 // search each searcher
162 TopDocs docs = searchables[i].Search(query, filter, nDocs);
163 totalHits += docs.totalHits; // update totalHits
164 ScoreDoc[] scoreDocs = docs.scoreDocs;
165 for (int j = 0; j < scoreDocs.Length; j++)
167 // merge scoreDocs into hq
168 ScoreDoc scoreDoc = scoreDocs[j];
169 scoreDoc.doc += starts[i]; // convert doc
170 if (!hq.Insert(scoreDoc))
171 break; // no more scores > minScore
175 ScoreDoc[] scoreDocs2 = new ScoreDoc[hq.Size()];
176 for (int i = hq.Size() - 1; i >= 0; i--)
177 // put docs in array
178 scoreDocs2[i] = (ScoreDoc) hq.Pop();
180 return new TopDocs(totalHits, scoreDocs2);
184 public override TopFieldDocs Search(Query query, Filter filter, int n, Sort sort)
186 FieldDocSortedHitQueue hq = null;
187 int totalHits = 0;
189 for (int i = 0; i < searchables.Length; i++)
191 // search each searcher
192 TopFieldDocs docs = searchables[i].Search(query, filter, n, sort);
193 if (hq == null)
194 hq = new FieldDocSortedHitQueue(docs.fields, n);
195 totalHits += docs.totalHits; // update totalHits
196 ScoreDoc[] scoreDocs = docs.scoreDocs;
197 for (int j = 0; j < scoreDocs.Length; j++)
199 // merge scoreDocs into hq
200 ScoreDoc scoreDoc = scoreDocs[j];
201 scoreDoc.doc += starts[i]; // convert doc
202 if (!hq.Insert(scoreDoc))
203 break; // no more scores > minScore
207 ScoreDoc[] scoreDocs2 = new ScoreDoc[hq.Size()];
208 for (int i = hq.Size() - 1; i >= 0; i--)
209 // put docs in array
210 scoreDocs2[i] = (ScoreDoc) hq.Pop();
212 return new TopFieldDocs(totalHits, scoreDocs2, hq.GetFields());
216 // inherit javadoc
217 public override void Search(Query query, Filter filter, HitCollector results)
219 for (int i = 0; i < searchables.Length; i++)
222 int start = starts[i];
224 searchables[i].Search(query, filter, new AnonymousClassHitCollector(results, start, this));
228 public override Query Rewrite(Query original)
230 Query[] queries = new Query[searchables.Length];
231 for (int i = 0; i < searchables.Length; i++)
233 queries[i] = searchables[i].Rewrite(original);
235 return original.Combine(queries);
238 public override Explanation Explain(Query query, int doc)
240 int i = SubSearcher(doc); // find searcher index
241 return searchables[i].Explain(query, doc - starts[i]); // dispatch to searcher