1 package org.apache.lucene.search; 2 3 18 19 import java.io.IOException ; 20 import java.util.ArrayList ; 21 import java.util.Arrays ; 22 import java.util.Comparator ; 23 24 31 class DisjunctionMaxScorer extends Scorer { 32 33 34 private ArrayList subScorers = new ArrayList (); 35 36 37 private float tieBreakerMultiplier; 38 39 private boolean more = false; private boolean firstTime = true; 42 45 public DisjunctionMaxScorer(float tieBreakerMultiplier, Similarity similarity) { 46 super(similarity); 47 this.tieBreakerMultiplier = tieBreakerMultiplier; 48 } 49 50 53 public void add(Scorer scorer) throws IOException { 54 if (scorer.next()) { subScorers.add(scorer); 56 more = true; 57 } 58 } 59 60 63 public boolean next() throws IOException { 64 if (!more) return false; 65 if (firstTime) { 66 heapify(); 67 firstTime = false; 68 return true; } 70 int lastdoc = ((Scorer) subScorers.get(0)).doc(); 72 do { 73 if (((Scorer) subScorers.get(0)).next()) 74 heapAdjust(0); 75 else { 76 heapRemoveRoot(); 77 if (subScorers.isEmpty()) return (more = false); 78 } 79 } while ( ((Scorer) subScorers.get(0)).doc()==lastdoc ); 80 return true; 81 } 82 83 86 public int doc() { 87 return ((Scorer) subScorers.get(0)).doc(); 88 } 89 90 93 public float score() throws IOException { 94 int doc = ((Scorer) subScorers.get(0)).doc(); 95 float[] sum = {((Scorer) subScorers.get(0)).score()}, max = {sum[0]}; 96 int size = subScorers.size(); 97 scoreAll(1, size, doc, sum, max); 98 scoreAll(2, size, doc, sum, max); 99 return max[0] + (sum[0] - max[0])*tieBreakerMultiplier; 100 } 101 102 private void scoreAll(int root, int size, int doc, float[] sum, float[] max) throws IOException { 104 if (root<size && ((Scorer) subScorers.get(root)).doc() == doc) { 105 float sub = ((Scorer) subScorers.get(root)).score(); 106 sum[0] += sub; 107 max[0] = Math.max(max[0], sub); 108 scoreAll((root<<1)+1, size, doc, sum, max); 109 scoreAll((root<<1)+2, size, doc, sum, max); 110 } 111 } 112 113 117 public boolean skipTo(int target) throws IOException { 118 while (subScorers.size()>0 && ((Scorer)subScorers.get(0)).doc()<target) { 119 if (((Scorer)subScorers.get(0)).skipTo(target)) 120 heapAdjust(0); 121 else 122 heapRemoveRoot(); 123 } 124 if ((subScorers.size()==0)) 125 return (more = false); 126 return true; 127 } 128 129 133 public Explanation explain(int doc) throws IOException { 134 throw new UnsupportedOperationException (); 135 } 136 137 private void heapify() { 139 int size = subScorers.size(); 140 for (int i=(size>>1)-1; i>=0; i--) 141 heapAdjust(i); 142 } 143 144 147 private void heapAdjust(int root) { 148 Scorer scorer=(Scorer)subScorers.get(root); 149 int doc=scorer.doc(); 150 int i=root, size=subScorers.size(); 151 while (i<=(size>>1)-1) { 152 int lchild=(i<<1)+1; 153 Scorer lscorer=(Scorer)subScorers.get(lchild); 154 int ldoc=lscorer.doc(); 155 int rdoc=Integer.MAX_VALUE, rchild=(i<<1)+2; 156 Scorer rscorer=null; 157 if (rchild<size) { 158 rscorer=(Scorer)subScorers.get(rchild); 159 rdoc=rscorer.doc(); 160 } 161 if (ldoc<doc) { 162 if (rdoc<ldoc) { 163 subScorers.set(i, rscorer); 164 subScorers.set(rchild, scorer); 165 i=rchild; 166 } else { 167 subScorers.set(i, lscorer); 168 subScorers.set(lchild, scorer); 169 i=lchild; 170 } 171 } else if (rdoc<doc) { 172 subScorers.set(i, rscorer); 173 subScorers.set(rchild, scorer); 174 i=rchild; 175 } else return; 176 } 177 } 178 179 private void heapRemoveRoot() { 181 int size=subScorers.size(); 182 if (size==1) 183 subScorers.remove(0); 184 else { 185 subScorers.set(0, subScorers.get(size-1)); 186 subScorers.remove(size-1); 187 heapAdjust(0); 188 } 189 } 190 191 } 192 | Popular Tags |