blob: 33adf448bee80490cd4437150f96c6f478db0b1f [file] [log] [blame]
Index: BooleanScorer.java
===================================================================
RCS file: /home/cvspublic/jakarta-lucene/src/java/org/apache/lucene/search/BooleanScorer.java,v
retrieving revision 1.14
diff -u -3 -p -u -w -r1.14 BooleanScorer.java
--- BooleanScorer.java 10 Dec 2004 19:36:40 -0000 1.14
+++ BooleanScorer.java 16 Jan 2005 21:09:17 -0000
@@ -1,7 +1,8 @@
package org.apache.lucene.search;
/**
- * Copyright 2004 The Apache Software Foundation
+ * Copyright 2005 Paul Elschot
+ * Derived from BooleanScorer of 16 January 2005.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +19,9 @@ package org.apache.lucene.search;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.Comparator;
+
final class BooleanScorer extends Scorer {
private SubScorer scorers = null;
private BucketTable bucketTable = new BucketTable(this);
@@ -35,7 +39,7 @@ final class BooleanScorer extends Scorer
static final class SubScorer {
public Scorer scorer;
- public boolean done;
+ public boolean done; // FIXME: remove from next list instead of marking done.
public boolean required = false;
public boolean prohibited = false;
public HitCollector collector;
@@ -173,6 +177,8 @@ final class BooleanScorer extends Scorer
more = true;
}
}
+
+ // bucketTable.sortValidListByDocNr(); // sort here to score next() docs in order.
} while (bucketTable.first != null || more);
return false;
@@ -184,6 +190,30 @@ final class BooleanScorer extends Scorer
return current.score * coordFactors[current.coord];
}
+ public boolean skipTo(int target) throws IOException {
+ if (target < end) {
+ bucketTable.removeSmallerDocsValidList(target);
+ current = bucketTable.first;
+ return (current != null) || next();
+ } else {
+ bucketTable.first = null; // clear valid list
+ boolean more = false;
+ for (SubScorer sub = scorers; sub != null; sub = sub.next) {
+ Scorer scorer = sub.scorer;
+ if (!sub.done) {
+ if (target > scorer.doc()) {
+ more = true;
+ } else if (scorer.skipTo(target)) {
+ more = true;
+ } else {
+ sub.done = true;
+ }
+ }
+ }
+ return more && next();
+ }
+ }
+
static final class Bucket {
int doc = -1; // tells if bucket is valid
float score; // incremental score
@@ -211,6 +241,54 @@ final class BooleanScorer extends Scorer
public HitCollector newCollector(int mask) {
return new Collector(mask, this);
}
+
+ void removeSmallerDocsValidList(int target) {
+ /* Throw away earlier computed scores, sigh. */
+ Bucket b = first;
+ Bucket prev = first;
+ while (b != null) {
+ if (b.doc >= target) {
+ prev = b;
+ b = b.next;
+ } else if (b == prev) { // delete first
+ b = b.next;
+ prev = b;
+ first = b;
+ } else { // delete later
+ b = b.next;
+ prev.next = b;
+ }
+ }
+ }
+
+ private Bucket[] tmpBuckets = new Bucket[SIZE];
+ void sortValidListByDocNr() { /* may not be needed */
+ Bucket b = first;
+ int nrValidBuckets = 0;
+ while (b != null) {
+ tmpBuckets[nrValidBuckets++] = b;
+ b = b.next;
+ }
+ Arrays.sort(tmpBuckets, 0, nrValidBuckets,
+ new Comparator() {
+ public int compare(Object b1, Object b2) {
+ return ((Bucket) b1).doc - ((Bucket) b2).doc;
+ }
+ }
+ );
+ if (nrValidBuckets > 0) {
+ first = tmpBuckets[0];
+ b = tmpBuckets[0];
+ for (int i = 1; i < nrValidBuckets; i++) {
+ if (b.doc >= tmpBuckets[i].doc) {
+ throw new AssertionError("tmpBuckets not sorted");
+ }
+ b.next = tmpBuckets[i];
+ b = tmpBuckets[i];
+ }
+ b.next = null;
+ }
+ }
}
static final class Collector extends HitCollector {
@@ -243,10 +321,6 @@ final class BooleanScorer extends Scorer
}
}
- public boolean skipTo(int target) {
- throw new UnsupportedOperationException();
- }
-
public Explanation explain(int doc) {
throw new UnsupportedOperationException();
}
@@ -261,6 +335,5 @@ final class BooleanScorer extends Scorer
buffer.append(")");
return buffer.toString();
}
-
}