| 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(); |
| } |
| - |
| |
| } |