You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jp...@apache.org on 2015/02/21 15:32:52 UTC
svn commit: r1661369 - in /lucene/dev/trunk/lucene: CHANGES.txt
core/src/java/org/apache/lucene/search/MultiCollector.java
core/src/test/org/apache/lucene/search/MultiCollectorTest.java
Author: jpountz
Date: Sat Feb 21 14:32:52 2015
New Revision: 1661369
URL: http://svn.apache.org/r1661369
Log:
LUCENE-6263: MultiCollector automatically caches scores when several collectors need them.
Modified:
lucene/dev/trunk/lucene/CHANGES.txt
lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiCollector.java
lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/MultiCollectorTest.java
Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1661369&r1=1661368&r2=1661369&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Sat Feb 21 14:32:52 2015
@@ -101,6 +101,9 @@ Optimizations
* LUCENE-6262: ConstantScoreQuery does not wrap the inner weight anymore when
scores are not required. (Adrien Grand)
+* LUCENE-6263: MultiCollector automatically caches scores when several
+ collectors need them. (Adrien Grand)
+
API Changes
* LUCENE-6204, LUCENE-6208: Simplify CompoundFormat: remove files()
Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiCollector.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiCollector.java?rev=1661369&r1=1661368&r2=1661369&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiCollector.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/MultiCollector.java Sat Feb 21 14:32:52 2015
@@ -86,10 +86,18 @@ public class MultiCollector implements C
}
}
+ private final boolean cacheScores;
private final Collector[] collectors;
private MultiCollector(Collector... collectors) {
this.collectors = collectors;
+ int numNeedsScores = 0;
+ for (Collector collector : collectors) {
+ if (collector.needsScores()) {
+ numNeedsScores += 1;
+ }
+ }
+ this.cacheScores = numNeedsScores >= 2;
}
@Override
@@ -108,19 +116,24 @@ public class MultiCollector implements C
for (int i = 0; i < collectors.length; ++i) {
leafCollectors[i] = collectors[i].getLeafCollector(context);
}
- return new MultiLeafCollector(leafCollectors);
+ return new MultiLeafCollector(leafCollectors, cacheScores);
}
private static class MultiLeafCollector implements LeafCollector {
+ private final boolean cacheScores;
private final LeafCollector[] collectors;
- private MultiLeafCollector(LeafCollector[] collectors) {
+ private MultiLeafCollector(LeafCollector[] collectors, boolean cacheScores) {
this.collectors = collectors;
+ this.cacheScores = cacheScores;
}
@Override
public void setScorer(Scorer scorer) throws IOException {
+ if (cacheScores) {
+ scorer = new ScoreCachingWrappingScorer(scorer);
+ }
for (LeafCollector c : collectors) {
c.setScorer(scorer);
}
Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/MultiCollectorTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/MultiCollectorTest.java?rev=1661369&r1=1661368&r2=1661369&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/MultiCollectorTest.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/MultiCollectorTest.java Sat Feb 21 14:32:52 2015
@@ -19,7 +19,11 @@ package org.apache.lucene.search;
import java.io.IOException;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.RandomIndexWriter;
+import org.apache.lucene.store.Directory;
import org.apache.lucene.util.LuceneTestCase;
import org.junit.Test;
@@ -69,7 +73,7 @@ public class MultiCollectorTest extends
final LeafCollector ac = c.getLeafCollector(null);
ac.collect(1);
c.getLeafCollector(null);
- c.getLeafCollector(null).setScorer(null);
+ c.getLeafCollector(null).setScorer(new FakeScorer());
}
@Test
@@ -91,7 +95,7 @@ public class MultiCollectorTest extends
LeafCollector ac = c.getLeafCollector(null);
ac.collect(1);
ac = c.getLeafCollector(null);
- ac.setScorer(null);
+ ac.setScorer(new FakeScorer());
for (DummyCollector dc : dcs) {
assertTrue(dc.collectCalled);
@@ -101,4 +105,65 @@ public class MultiCollectorTest extends
}
+ private static Collector collector(boolean needsScores, Class<?> expectedScorer) {
+ return new Collector() {
+
+ @Override
+ public LeafCollector getLeafCollector(LeafReaderContext context) throws IOException {
+ return new LeafCollector() {
+
+ @Override
+ public void setScorer(Scorer scorer) throws IOException {
+ assertEquals(expectedScorer, scorer.getClass());
+ }
+
+ @Override
+ public void collect(int doc) throws IOException {}
+
+ };
+ }
+
+ @Override
+ public boolean needsScores() {
+ return needsScores;
+ }
+
+ };
+ }
+
+ public void testCacheScoresIfNecessary() throws IOException {
+ Directory dir = newDirectory();
+ RandomIndexWriter iw = new RandomIndexWriter(random(), dir);
+ iw.addDocument(new Document());
+ iw.commit();
+ DirectoryReader reader = iw.getReader();
+ iw.close();
+
+ final LeafReaderContext ctx = reader.leaves().get(0);
+
+ try {
+ collector(false, ScoreCachingWrappingScorer.class).getLeafCollector(ctx).setScorer(new FakeScorer());
+ fail("The collector was configured to expect a ScoreCachingWrappingScorer and did not fail when pass in a FakeScorer");
+ } catch (AssertionError e) {
+ // expected
+ }
+
+ // no collector needs scores => no caching
+ Collector c1 = collector(false, FakeScorer.class);
+ Collector c2 = collector(false, FakeScorer.class);
+ MultiCollector.wrap(c1, c2).getLeafCollector(ctx).setScorer(new FakeScorer());
+
+ // only one collector needs scores => no caching
+ c1 = collector(true, FakeScorer.class);
+ c2 = collector(false, FakeScorer.class);
+ MultiCollector.wrap(c1, c2).getLeafCollector(ctx).setScorer(new FakeScorer());
+
+ // several collectors need scores => caching
+ c1 = collector(true, ScoreCachingWrappingScorer.class);
+ c2 = collector(true, ScoreCachingWrappingScorer.class);
+ MultiCollector.wrap(c1, c2).getLeafCollector(ctx).setScorer(new FakeScorer());
+
+ reader.close();
+ dir.close();
+ }
}