Thumbnail file hits. Based on a patch from D Bera
[beagle.git] / beagled / Lucene.Net / Search / Hits.cs
blob965a6fe4c96860138933a2555107fbd9d2ac3e60
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 namespace Lucene.Net.Search
21 /// <summary>A ranked list of documents, used to hold search results. </summary>
22 public sealed class Hits
24 private Query query;
25 private Searcher searcher;
26 private Filter filter = null;
27 private Sort sort = null;
29 private int length; // the total number of hits
30 private System.Collections.ArrayList hitDocs = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); // cache of hits retrieved
32 private HitDoc first; // head of LRU cache
33 private HitDoc last; // tail of LRU cache
34 private int numDocs = 0; // number cached
35 private int maxDocs = 200; // max to cache
37 internal Hits(Searcher s, Query q, Filter f)
39 query = q;
40 searcher = s;
41 filter = f;
42 GetMoreDocs(50); // retrieve 100 initially
45 internal Hits(Searcher s, Query q, Filter f, Sort o)
47 query = q;
48 searcher = s;
49 filter = f;
50 sort = o;
51 GetMoreDocs(50); // retrieve 100 initially
54 /// <summary> Tries to add new documents to hitDocs.
55 /// Ensures that the hit numbered <code>min</code> has been retrieved.
56 /// </summary>
57 private void GetMoreDocs(int min)
59 if (hitDocs.Count > min)
61 min = hitDocs.Count;
64 int n = min * 2; // double # retrieved
65 TopDocs topDocs = (sort == null) ? searcher.Search(query, filter, n) : searcher.Search(query, filter, n, sort);
66 length = topDocs.totalHits;
67 ScoreDoc[] scoreDocs = topDocs.scoreDocs;
69 float scoreNorm = 1.0f;
70 if (length > 0 && scoreDocs[0].score > 1.0f)
72 scoreNorm = 1.0f / scoreDocs[0].score;
75 int end = scoreDocs.Length < length?scoreDocs.Length:length;
76 for (int i = hitDocs.Count; i < end; i++)
78 hitDocs.Add(new HitDoc(scoreDocs[i].score * scoreNorm, scoreDocs[i].doc));
82 /// <summary>Returns the total number of hits available in this set. </summary>
83 public int Length()
85 return length;
88 /// <summary>Returns the stored fields of the n<sup>th</sup> document in this set.
89 /// <p>Documents are cached, so that repeated requests for the same element may
90 /// return the same Document object.
91 /// </summary>
92 public Document Doc(int n)
94 HitDoc hitDoc = HitDoc(n);
96 // Update LRU cache of documents
97 Remove(hitDoc); // remove from list, if there
98 AddToFront(hitDoc); // add to front of list
99 if (numDocs > maxDocs)
101 // if cache is full
102 HitDoc oldLast = last;
103 Remove(last); // flush last
104 oldLast.doc = null; // let doc get gc'd
107 if (hitDoc.doc == null)
109 hitDoc.doc = searcher.Doc(hitDoc.id); // cache miss: read document
112 return hitDoc.doc;
115 /// <summary>Returns the score for the nth document in this set. </summary>
116 public float Score(int n)
118 return HitDoc(n).score;
121 /// <summary>Returns the id for the nth document in this set. </summary>
122 public int Id(int n)
124 return HitDoc(n).id;
128 private HitDoc HitDoc(int n)
130 if (n >= length)
132 throw new System.IndexOutOfRangeException("Not a valid hit number: " + n);
135 if (n >= hitDocs.Count)
137 GetMoreDocs(n);
140 return (HitDoc) hitDocs[n];
143 private void AddToFront(HitDoc hitDoc)
145 // insert at front of cache
146 if (first == null)
148 last = hitDoc;
150 else
152 first.prev = hitDoc;
155 hitDoc.next = first;
156 first = hitDoc;
157 hitDoc.prev = null;
159 numDocs++;
162 private void Remove(HitDoc hitDoc)
164 // remove from cache
165 if (hitDoc.doc == null)
167 // it's not in the list
168 return ; // abort
171 if (hitDoc.next == null)
173 last = hitDoc.prev;
175 else
177 hitDoc.next.prev = hitDoc.prev;
180 if (hitDoc.prev == null)
182 first = hitDoc.next;
184 else
186 hitDoc.prev.next = hitDoc.next;
189 numDocs--;
193 sealed class HitDoc
195 internal float score;
196 internal int id;
197 internal Document doc = null;
199 internal HitDoc next; // in doubly-linked cache
200 internal HitDoc prev; // in doubly-linked cache
202 internal HitDoc(float s, int i)
204 score = s;
205 id = i;