1 package org.apache.lucene.search; 2 3 18 19 import java.io.IOException ; 20 import java.util.Vector ; 21 import java.util.Iterator ; 22 23 import org.apache.lucene.document.Document; 24 25 26 public final class Hits { 27 private Weight weight; 28 private Searcher searcher; 29 private Filter filter = null; 30 private Sort sort = null; 31 32 private int length; private Vector hitDocs = new Vector (); 35 private HitDoc first; private HitDoc last; private int numDocs = 0; private int maxDocs = 200; 40 Hits(Searcher s, Query q, Filter f) throws IOException { 41 weight = q.weight(s); 42 searcher = s; 43 filter = f; 44 getMoreDocs(50); } 46 47 Hits(Searcher s, Query q, Filter f, Sort o) throws IOException { 48 weight = q.weight(s); 49 searcher = s; 50 filter = f; 51 sort = o; 52 getMoreDocs(50); } 54 55 59 private final void getMoreDocs(int min) throws IOException { 60 if (hitDocs.size() > min) { 61 min = hitDocs.size(); 62 } 63 64 int n = min * 2; TopDocs topDocs = (sort == null) ? searcher.search(weight, filter, n) : searcher.search(weight, filter, n, sort); 66 length = topDocs.totalHits; 67 ScoreDoc[] scoreDocs = topDocs.scoreDocs; 68 69 float scoreNorm = 1.0f; 70 71 if (length > 0 && topDocs.getMaxScore() > 1.0f) { 72 scoreNorm = 1.0f / topDocs.getMaxScore(); 73 } 74 75 int end = scoreDocs.length < length ? scoreDocs.length : length; 76 for (int i = hitDocs.size(); i < end; i++) { 77 hitDocs.addElement(new HitDoc(scoreDocs[i].score * scoreNorm, 78 scoreDocs[i].doc)); 79 } 80 } 81 82 83 public final int length() { 84 return length; 85 } 86 87 90 public final Document doc(int n) throws IOException { 91 HitDoc hitDoc = hitDoc(n); 92 93 remove(hitDoc); addToFront(hitDoc); if (numDocs > maxDocs) { HitDoc oldLast = last; 98 remove(last); oldLast.doc = null; } 101 102 if (hitDoc.doc == null) { 103 hitDoc.doc = searcher.doc(hitDoc.id); } 105 106 return hitDoc.doc; 107 } 108 109 110 public final float score(int n) throws IOException { 111 return hitDoc(n).score; 112 } 113 114 115 public final int id(int n) throws IOException { 116 return hitDoc(n).id; 117 } 118 119 128 public Iterator iterator() { 129 return new HitIterator(this); 130 } 131 132 private final HitDoc hitDoc(int n) throws IOException { 133 if (n >= length) { 134 throw new IndexOutOfBoundsException ("Not a valid hit number: " + n); 135 } 136 137 if (n >= hitDocs.size()) { 138 getMoreDocs(n); 139 } 140 141 return (HitDoc) hitDocs.elementAt(n); 142 } 143 144 private final void addToFront(HitDoc hitDoc) { if (first == null) { 146 last = hitDoc; 147 } else { 148 first.prev = hitDoc; 149 } 150 151 hitDoc.next = first; 152 first = hitDoc; 153 hitDoc.prev = null; 154 155 numDocs++; 156 } 157 158 private final void remove(HitDoc hitDoc) { if (hitDoc.doc == null) { return; } 162 163 if (hitDoc.next == null) { 164 last = hitDoc.prev; 165 } else { 166 hitDoc.next.prev = hitDoc.prev; 167 } 168 169 if (hitDoc.prev == null) { 170 first = hitDoc.next; 171 } else { 172 hitDoc.prev.next = hitDoc.next; 173 } 174 175 numDocs--; 176 } 177 } 178 179 final class HitDoc { 180 float score; 181 int id; 182 Document doc = null; 183 184 HitDoc next; HitDoc prev; 187 HitDoc(float s, int i) { 188 score = s; 189 id = i; 190 } 191 } 192 | Popular Tags |