001 package gate.creole.annic.apache.lucene.search;
002
003 /**
004 * Copyright 2004 The Apache Software Foundation
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 import java.io.IOException;
020
021 import gate.creole.annic.apache.lucene.index.*;
022
023 abstract class PhraseScorer extends Scorer {
024 private Weight weight;
025 protected byte[] norms;
026 protected float value;
027
028 private boolean firstTime = true;
029 private boolean more = true;
030 protected PhraseQueue pq;
031 protected PhrasePositions first, last;
032
033 private float freq;
034
035 PhraseScorer(Weight weight, TermPositions[] tps, java.util.Vector positions, Similarity similarity,
036 byte[] norms, Searcher searcher) throws IOException {
037 super(similarity);
038 this.norms = norms;
039 this.weight = weight;
040 this.value = weight.getValue();
041 this.searcher = searcher;
042
043 // convert tps to a list
044 for (int i = 0; i < tps.length; i++) {
045 PhrasePositions pp = new PhrasePositions(tps[i], ((Integer)positions.get(i)).intValue());
046 if (last != null) { // add next to end of list
047 last.next = pp;
048 } else
049 first = pp;
050
051 last = pp;
052 }
053
054 pq = new PhraseQueue(tps.length); // construct empty pq
055
056 }
057
058 PhraseScorer(Weight weight, TermPositions[] tps, Similarity similarity,
059 byte[] norms) throws IOException {
060 super(similarity);
061 this.norms = norms;
062 this.weight = weight;
063 this.value = weight.getValue();
064
065 // convert tps to a list
066 for (int i = 0; i < tps.length; i++) {
067 PhrasePositions pp = new PhrasePositions(tps[i], i);
068 if (last != null) { // add next to end of list
069 last.next = pp;
070 } else
071 first = pp;
072
073 last = pp;
074 }
075
076 pq = new PhraseQueue(tps.length); // construct empty pq
077
078 }
079
080 public int doc() { return first.doc; }
081
082 public boolean next(Searcher searcher) throws IOException {
083 this.searcher = searcher;
084 if (firstTime) {
085 init();
086 firstTime = false;
087 } else if (more) {
088 more = last.next(); // trigger further scanning
089 }
090 return doNext();
091 }
092
093 // next without initial increment
094 private boolean doNext() throws IOException {
095 while (more) {
096 while (more && first.doc < last.doc) { // find doc w/ all the terms
097 more = first.skipTo(last.doc); // skip first upto last
098 firstToLast(); // and move it to the end
099 }
100
101 if (more) {
102 // found a doc with all of the terms
103 freq = phraseFreq(); // check for phrase
104 if (freq == 0.0f) // no match
105 more = last.next(); // trigger further scanning
106 else
107 return true; // found a match
108 }
109 }
110 return false; // no more matches
111 }
112
113 public float score(Searcher searcher) throws IOException {
114 this.searcher = searcher;
115 float raw = getSimilarity().tf(freq) * value; // raw score
116 return raw * Similarity.decodeNorm(norms[first.doc]); // normalize
117 }
118
119 public boolean skipTo(int target) throws IOException {
120 for (PhrasePositions pp = first; more && pp != null; pp = pp.next) {
121 more = pp.skipTo(target);
122 }
123 if (more)
124 sort(); // re-sort
125 return doNext();
126 }
127
128 protected abstract float phraseFreq() throws IOException;
129
130 private void init() throws IOException {
131 for (PhrasePositions pp = first; more && pp != null; pp = pp.next)
132 more = pp.next();
133 if(more)
134 sort();
135 }
136
137 private void sort() {
138 pq.clear();
139 for (PhrasePositions pp = first; pp != null; pp = pp.next)
140 pq.put(pp);
141 pqToList();
142 }
143
144 protected final void pqToList() {
145 last = first = null;
146 while (pq.top() != null) {
147 PhrasePositions pp = (PhrasePositions) pq.pop();
148 if (last != null) { // add next to end of list
149 last.next = pp;
150 } else
151 first = pp;
152 last = pp;
153 pp.next = null;
154 }
155 }
156
157 protected final void firstToLast() {
158 last.next = first; // move first to end of list
159 last = first;
160 first = first.next;
161 last.next = null;
162 }
163
164 public Explanation explain(final int doc) throws IOException {
165 Explanation tfExplanation = new Explanation();
166
167 while (next(this.searcher) && doc() < doc) {}
168
169 float phraseFreq = (doc() == doc) ? freq : 0.0f;
170 tfExplanation.setValue(getSimilarity().tf(phraseFreq));
171 tfExplanation.setDescription("tf(phraseFreq=" + phraseFreq + ")");
172
173 return tfExplanation;
174 }
175
176 public String toString() { return "scorer(" + weight + ")"; }
177
178 }
|