You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by sh...@apache.org on 2017/03/31 13:57:51 UTC
[3/3] lucene-solr:feature/autoscaling: LUCENE-7755: Join queries
should not reference IndexReaders.
LUCENE-7755: Join queries should not reference IndexReaders.
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/b54b08db
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/b54b08db
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/b54b08db
Branch: refs/heads/feature/autoscaling
Commit: b54b08db7d3b96828408866008e389cf03fcaf58
Parents: 6c17c6e
Author: Adrien Grand <jp...@gmail.com>
Authored: Thu Mar 30 15:11:52 2017 +0200
Committer: Shalin Shekhar Mangar <sh...@apache.org>
Committed: Fri Mar 31 19:27:36 2017 +0530
----------------------------------------------------------------------
lucene/CHANGES.txt | 7 +++++++
.../org/apache/lucene/index/IndexReaderContext.java | 10 +++++++++-
.../lucene/search/join/GlobalOrdinalsQuery.java | 16 ++++++++++------
.../search/join/GlobalOrdinalsWithScoreQuery.java | 16 ++++++++++------
.../org/apache/lucene/search/join/JoinUtil.java | 8 +++-----
5 files changed, 39 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b54b08db/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 92f01a9..da643ff 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -93,6 +93,13 @@ Other
* LUCENE-7743: Never call new String(String).
(Daniel Jelinski via Adrien Grand)
+======================= Lucene 6.5.1 =======================
+
+Bug Fixes
+
+* LUCENE-7755: Fixed join queries to not reference IndexReaders, as it could
+ cause leaks if they are cached. (Adrien Grand)
+
======================= Lucene 6.5.0 =======================
API Changes
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b54b08db/lucene/core/src/java/org/apache/lucene/index/IndexReaderContext.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/IndexReaderContext.java b/lucene/core/src/java/org/apache/lucene/index/IndexReaderContext.java
index dada3ff..bca7a14 100644
--- a/lucene/core/src/java/org/apache/lucene/index/IndexReaderContext.java
+++ b/lucene/core/src/java/org/apache/lucene/index/IndexReaderContext.java
@@ -46,7 +46,15 @@ public abstract class IndexReaderContext {
this.ordInParent = ordInParent;
this.isTopLevel = parent==null;
}
-
+
+ /** Expert: Return an {@link Object} that uniquely identifies this context.
+ * The returned object does neither reference this {@link IndexReaderContext}
+ * nor the wrapped {@link IndexReader}.
+ * @lucene.experimental */
+ public Object id() {
+ return identity;
+ }
+
/** Returns the {@link IndexReader}, this context represents. */
public abstract IndexReader reader();
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b54b08db/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsQuery.java
----------------------------------------------------------------------
diff --git a/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsQuery.java
index 93edcc0..5aaca1a 100644
--- a/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsQuery.java
+++ b/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsQuery.java
@@ -20,7 +20,7 @@ import java.io.IOException;
import java.util.Set;
import org.apache.lucene.index.DocValues;
-import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.MultiDocValues;
import org.apache.lucene.index.SortedDocValues;
@@ -48,19 +48,23 @@ final class GlobalOrdinalsQuery extends Query {
// just for hashcode and equals:
private final Query fromQuery;
- private final IndexReader indexReader;
+ // id of the context rather than the context itself in order not to hold references to index readers
+ private final Object indexReaderContextId;
- GlobalOrdinalsQuery(LongBitSet foundOrds, String joinField, MultiDocValues.OrdinalMap globalOrds, Query toQuery, Query fromQuery, IndexReader indexReader) {
+ GlobalOrdinalsQuery(LongBitSet foundOrds, String joinField, MultiDocValues.OrdinalMap globalOrds, Query toQuery, Query fromQuery, IndexReaderContext context) {
this.foundOrds = foundOrds;
this.joinField = joinField;
this.globalOrds = globalOrds;
this.toQuery = toQuery;
this.fromQuery = fromQuery;
- this.indexReader = indexReader;
+ this.indexReaderContextId = context.id();
}
@Override
public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
+ if (searcher.getTopReaderContext().id() != indexReaderContextId) {
+ throw new IllegalStateException("Creating the weight against a different index reader than this query has been built for.");
+ }
return new W(this, toQuery.createWeight(searcher, false, 1f), boost);
}
@@ -74,7 +78,7 @@ final class GlobalOrdinalsQuery extends Query {
return fromQuery.equals(other.fromQuery) &&
joinField.equals(other.joinField) &&
toQuery.equals(other.toQuery) &&
- indexReader.equals(other.indexReader);
+ indexReaderContextId.equals(other.indexReaderContextId);
}
@Override
@@ -83,7 +87,7 @@ final class GlobalOrdinalsQuery extends Query {
result = 31 * result + joinField.hashCode();
result = 31 * result + toQuery.hashCode();
result = 31 * result + fromQuery.hashCode();
- result = 31 * result + indexReader.hashCode();
+ result = 31 * result + indexReaderContextId.hashCode();
return result;
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b54b08db/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsWithScoreQuery.java
----------------------------------------------------------------------
diff --git a/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsWithScoreQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsWithScoreQuery.java
index 0aedf35..5e614ea 100644
--- a/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsWithScoreQuery.java
+++ b/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsWithScoreQuery.java
@@ -20,7 +20,7 @@ import java.io.IOException;
import java.util.Set;
import org.apache.lucene.index.DocValues;
-import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.MultiDocValues;
import org.apache.lucene.index.SortedDocValues;
@@ -48,9 +48,10 @@ final class GlobalOrdinalsWithScoreQuery extends Query {
private final Query fromQuery;
private final int min;
private final int max;
- private final IndexReader indexReader;
+ // id of the context rather than the context itself in order not to hold references to index readers
+ private final Object indexReaderContextId;
- GlobalOrdinalsWithScoreQuery(GlobalOrdinalsWithScoreCollector collector, String joinField, MultiDocValues.OrdinalMap globalOrds, Query toQuery, Query fromQuery, int min, int max, IndexReader indexReader) {
+ GlobalOrdinalsWithScoreQuery(GlobalOrdinalsWithScoreCollector collector, String joinField, MultiDocValues.OrdinalMap globalOrds, Query toQuery, Query fromQuery, int min, int max, IndexReaderContext context) {
this.collector = collector;
this.joinField = joinField;
this.globalOrds = globalOrds;
@@ -58,11 +59,14 @@ final class GlobalOrdinalsWithScoreQuery extends Query {
this.fromQuery = fromQuery;
this.min = min;
this.max = max;
- this.indexReader = indexReader;
+ this.indexReaderContextId = context.id();
}
@Override
public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
+ if (searcher.getTopReaderContext().id() != indexReaderContextId) {
+ throw new IllegalStateException("Creating the weight against a different index reader than this query has been built for.");
+ }
return new W(this, toQuery.createWeight(searcher, false, 1f));
}
@@ -78,7 +82,7 @@ final class GlobalOrdinalsWithScoreQuery extends Query {
joinField.equals(other.joinField) &&
fromQuery.equals(other.fromQuery) &&
toQuery.equals(other.toQuery) &&
- indexReader.equals(other.indexReader);
+ indexReaderContextId.equals(other.indexReaderContextId);
}
@Override
@@ -89,7 +93,7 @@ final class GlobalOrdinalsWithScoreQuery extends Query {
result = 31 * result + fromQuery.hashCode();
result = 31 * result + min;
result = 31 * result + max;
- result = 31 * result + indexReader.hashCode();
+ result = 31 * result + indexReaderContextId.hashCode();
return result;
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b54b08db/lucene/join/src/java/org/apache/lucene/search/join/JoinUtil.java
----------------------------------------------------------------------
diff --git a/lucene/join/src/java/org/apache/lucene/search/join/JoinUtil.java b/lucene/join/src/java/org/apache/lucene/search/join/JoinUtil.java
index bfc1f9b..537b224 100644
--- a/lucene/join/src/java/org/apache/lucene/search/join/JoinUtil.java
+++ b/lucene/join/src/java/org/apache/lucene/search/join/JoinUtil.java
@@ -32,7 +32,6 @@ import org.apache.lucene.document.LongPoint;
import org.apache.lucene.index.BinaryDocValues;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.DocValuesType;
-import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.MultiDocValues;
@@ -467,8 +466,7 @@ public final class JoinUtil {
MultiDocValues.OrdinalMap ordinalMap,
int min,
int max) throws IOException {
- IndexReader indexReader = searcher.getIndexReader();
- int numSegments = indexReader.leaves().size();
+ int numSegments = searcher.getIndexReader().leaves().size();
final long valueCount;
if (numSegments == 0) {
return new MatchNoDocsQuery("JoinUtil.createJoinQuery with no segments");
@@ -509,7 +507,7 @@ public final class JoinUtil {
if (min <= 0 && max == Integer.MAX_VALUE) {
GlobalOrdinalsCollector globalOrdinalsCollector = new GlobalOrdinalsCollector(joinField, ordinalMap, valueCount);
searcher.search(rewrittenFromQuery, globalOrdinalsCollector);
- return new GlobalOrdinalsQuery(globalOrdinalsCollector.getCollectorOrdinals(), joinField, ordinalMap, rewrittenToQuery, rewrittenFromQuery, indexReader);
+ return new GlobalOrdinalsQuery(globalOrdinalsCollector.getCollectorOrdinals(), joinField, ordinalMap, rewrittenToQuery, rewrittenFromQuery, searcher.getTopReaderContext());
} else {
globalOrdinalsWithScoreCollector = new GlobalOrdinalsWithScoreCollector.NoScore(joinField, ordinalMap, valueCount, min, max);
break;
@@ -518,7 +516,7 @@ public final class JoinUtil {
throw new IllegalArgumentException(String.format(Locale.ROOT, "Score mode %s isn't supported.", scoreMode));
}
searcher.search(rewrittenFromQuery, globalOrdinalsWithScoreCollector);
- return new GlobalOrdinalsWithScoreQuery(globalOrdinalsWithScoreCollector, joinField, ordinalMap, rewrittenToQuery, rewrittenFromQuery, min, max, indexReader);
+ return new GlobalOrdinalsWithScoreQuery(globalOrdinalsWithScoreCollector, joinField, ordinalMap, rewrittenToQuery, rewrittenFromQuery, min, max, searcher.getTopReaderContext());
}
}