Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions core/src/main/java/org/apache/lucene/queries/MinDocQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package org.apache.lucene.queries;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.ConstantScoreScorer;
import org.apache.lucene.search.ConstantScoreWeight;
Expand All @@ -35,16 +36,26 @@
* to a configured doc ID. */
public final class MinDocQuery extends Query {

// Matching documents depend on the sequence of segments that the index reader
// wraps. Yet matches must be cacheable per-segment, so we need to incorporate
// the reader id in the identity of the query so that a cache entry may only
// be reused if this query is run against the same index reader.
private final Object readerId;
private final int minDoc;

/** Sole constructor. */
public MinDocQuery(int minDoc) {
this(minDoc, null);
}

MinDocQuery(int minDoc, Object readerId) {
this.minDoc = minDoc;
this.readerId = readerId;
}

@Override
public int hashCode() {
return Objects.hash(classHash(), minDoc);
return Objects.hash(classHash(), minDoc, readerId);
}

@Override
Expand All @@ -53,11 +64,24 @@ public boolean equals(Object obj) {
return false;
}
MinDocQuery that = (MinDocQuery) obj;
return minDoc == that.minDoc;
return minDoc == that.minDoc && Objects.equals(readerId, that.readerId);
}

@Override
public Query rewrite(IndexReader reader) throws IOException {
if (Objects.equals(reader.getContext().id(), readerId) == false) {
return new MinDocQuery(minDoc, reader.getContext().id());
}
return this;
}

@Override
public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
if (readerId == null) {
throw new IllegalStateException("Rewrite first");
} else if (Objects.equals(searcher.getIndexReader().getContext().id(), readerId) == false) {
throw new IllegalStateException("Executing against a different reader than the query has been rewritten against");
}
return new ConstantScoreWeight(this, boost) {
@Override
public Scorer scorer(LeafReaderContext context) throws IOException {
Expand Down
15 changes: 15 additions & 0 deletions core/src/test/java/org/apache/lucene/queries/MinDocQueryTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@

import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiReader;
import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.QueryUtils;
import org.apache.lucene.store.Directory;
import org.elasticsearch.test.ESTestCase;
Expand All @@ -38,6 +40,19 @@ public void testBasics() {
QueryUtils.check(query1);
QueryUtils.checkEqual(query1, query2);
QueryUtils.checkUnequal(query1, query3);

MinDocQuery query4 = new MinDocQuery(42, new Object());
MinDocQuery query5 = new MinDocQuery(42, new Object());
QueryUtils.checkUnequal(query4, query5);
}

public void testRewrite() throws Exception {
IndexReader reader = new MultiReader();
MinDocQuery query = new MinDocQuery(42);
Query rewritten = query.rewrite(reader);
QueryUtils.checkUnequal(query, rewritten);
Query rewritten2 = rewritten.rewrite(reader);
assertSame(rewritten, rewritten2);
}

public void testRandom() throws IOException {
Expand Down