LUCENE-2831: attempt to use the correct reader context rather than doing getTopReaderContext on a leaf

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056585 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2011-01-08 01:17:43 +00:00
parent cd90c9a911
commit 1aa40cd395
9 changed files with 72 additions and 16 deletions

View File

@ -342,8 +342,8 @@ class SpatialDistanceQuery extends Query {
public SpatialWeight(IndexSearcher searcher) throws IOException { public SpatialWeight(IndexSearcher searcher) throws IOException {
this.searcher = searcher; this.searcher = searcher;
this.latContext = latSource.newContext(); this.latContext = latSource.newContext(searcher);
this.lonContext = lonSource.newContext(); this.lonContext = lonSource.newContext(searcher);
latSource.createWeight(latContext, searcher); latSource.createWeight(latContext, searcher);
lonSource.createWeight(lonContext, searcher); lonSource.createWeight(lonContext, searcher);
} }

View File

@ -151,7 +151,7 @@ public class Grouping {
@Override @Override
void prepare() throws IOException { void prepare() throws IOException {
Map context = ValueSource.newContext(); Map context = ValueSource.newContext(searcher);
groupBy.createWeight(context, searcher); groupBy.createWeight(context, searcher);
} }

View File

@ -62,7 +62,7 @@ public class SolrConstantScoreQuery extends ConstantScoreQuery {
public ConstantWeight(IndexSearcher searcher) throws IOException { public ConstantWeight(IndexSearcher searcher) throws IOException {
this.similarity = getSimilarity(searcher); this.similarity = getSimilarity(searcher);
this.context = ValueSource.newContext(); this.context = ValueSource.newContext(searcher);
if (filter instanceof SolrFilter) if (filter instanceof SolrFilter)
((SolrFilter)filter).createWeight(context, searcher); ((SolrFilter)filter).createWeight(context, searcher);
} }

View File

@ -890,8 +890,6 @@ abstract class Double2Parser extends NamedParser {
@Override @Override
public void createWeight(Map context, IndexSearcher searcher) throws IOException { public void createWeight(Map context, IndexSearcher searcher) throws IOException {
a.createWeight(context,searcher);
b.createWeight(context,searcher);
} }
public int hashCode() { public int hashCode() {

View File

@ -66,7 +66,7 @@ public class BoostedQuery extends Query {
public BoostedWeight(IndexSearcher searcher) throws IOException { public BoostedWeight(IndexSearcher searcher) throws IOException {
this.searcher = searcher; this.searcher = searcher;
this.qWeight = q.weight(searcher); this.qWeight = q.weight(searcher);
this.context = boostVal.newContext(); this.context = boostVal.newContext(searcher);
boostVal.createWeight(context,searcher); boostVal.createWeight(context,searcher);
} }

View File

@ -67,7 +67,7 @@ public class FunctionQuery extends Query {
public FunctionWeight(IndexSearcher searcher) throws IOException { public FunctionWeight(IndexSearcher searcher) throws IOException {
this.searcher = searcher; this.searcher = searcher;
this.context = func.newContext(); this.context = func.newContext(searcher);
func.createWeight(context, searcher); func.createWeight(context, searcher);
} }

View File

@ -44,8 +44,8 @@ public class QueryValueSource extends ValueSource {
} }
@Override @Override
public DocValues getValues(Map context, IndexReader reader) throws IOException { public DocValues getValues(Map fcontext, IndexReader reader) throws IOException {
return new QueryDocValues(reader, q, defVal, context==null ? null : (Weight)context.get(this)); return new QueryDocValues(reader, q, defVal, fcontext);
} }
public int hashCode() { public int hashCode() {
@ -71,6 +71,7 @@ class QueryDocValues extends DocValues {
final IndexReader reader; final IndexReader reader;
final Weight weight; final Weight weight;
final float defVal; final float defVal;
final Map fcontext;
Scorer scorer; Scorer scorer;
int scorerDoc; // the document the scorer is on int scorerDoc; // the document the scorer is on
@ -79,18 +80,36 @@ class QueryDocValues extends DocValues {
// to trigger a scorer reset on first access. // to trigger a scorer reset on first access.
int lastDocRequested=Integer.MAX_VALUE; int lastDocRequested=Integer.MAX_VALUE;
public QueryDocValues(IndexReader reader, Query q, float defVal, Weight w) throws IOException { public QueryDocValues(IndexReader reader, Query q, float defVal, Map fcontext) throws IOException {
this.reader = reader; this.reader = reader;
this.q = q; this.q = q;
this.defVal = defVal; this.defVal = defVal;
weight = w!=null ? w : q.weight(new IndexSearcher(reader)); this.fcontext = fcontext;
Weight w = fcontext==null ? null : (Weight)fcontext.get(q);
if (w == null) {
IndexSearcher weightSearcher = fcontext == null ? new IndexSearcher(reader) : (IndexSearcher)fcontext.get("searcher");
// TODO: sort by function doesn't weight (SOLR-1297 is open because of this bug)... so weightSearcher will currently be null
if (weightSearcher == null) weightSearcher = new IndexSearcher(reader);
w = q.weight(weightSearcher);
}
weight = w;
} }
public float floatVal(int doc) { public float floatVal(int doc) {
try { try {
if (doc < lastDocRequested) { if (doc < lastDocRequested) {
// out-of-order access.... reset scorer. // out-of-order access.... reset scorer.
scorer = weight.scorer(reader.getTopReaderContext(), true, false); IndexReader.AtomicReaderContext ctx = ValueSource.readerToContext(fcontext, reader);
if (ctx == null) {
// TODO: this is because SOLR-1297 does not weight
ctx = (IndexReader.AtomicReaderContext)reader.getTopReaderContext(); // this is the incorrect context
}
scorer = weight.scorer(ctx, true, false);
if (scorer==null) return defVal; if (scorer==null) return defVal;
scorerDoc = -1; scorerDoc = -1;
} }

View File

@ -18,6 +18,8 @@
package org.apache.solr.search.function; package org.apache.solr.search.function;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexReader.AtomicReaderContext;
import org.apache.lucene.index.IndexReader.ReaderContext;
import org.apache.lucene.search.FieldComparator; import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.FieldComparatorSource; import org.apache.lucene.search.FieldComparatorSource;
import org.apache.lucene.search.Scorer; import org.apache.lucene.search.Scorer;
@ -25,6 +27,7 @@ import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.SortField; import org.apache.lucene.search.SortField;
import org.apache.lucene.util.Bits; import org.apache.lucene.util.Bits;
import org.apache.lucene.index.MultiFields; import org.apache.lucene.index.MultiFields;
import org.apache.solr.common.SolrException;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
@ -90,10 +93,46 @@ public abstract class ValueSource implements Serializable {
/** /**
* Returns a new non-threadsafe context map. * Returns a new non-threadsafe context map.
*/ */
public static Map newContext() { public static Map newContext(IndexSearcher searcher) {
return new IdentityHashMap(); Map context = new IdentityHashMap();
context.put("searcher", searcher);
return context;
} }
/* @lucene.internal
* This will most likely go away in the future.
*/
public static AtomicReaderContext readerToContext(Map fcontext, IndexReader reader) {
Object v = fcontext.get(reader);
if (v == null) {
IndexSearcher searcher = (IndexSearcher)fcontext.get("searcher");
if (searcher == null) {
return null;
// TODO
// throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "no searcher found in function context");
}
ReaderContext rcontext = searcher.getIndexReader().getTopReaderContext();
if (rcontext.isAtomic) {
assert rcontext.reader == reader;
fcontext.put(rcontext.reader, (AtomicReaderContext)rcontext);
} else {
for (AtomicReaderContext subCtx : rcontext.leaves()) {
fcontext.put(subCtx.reader, subCtx);
}
}
v = fcontext.get(reader);
if (v == null) {
return null;
// TODO
// throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "reader " + reader + " is not from the top reader " + searcher.getIndexReader());
}
}
return (AtomicReaderContext)v;
}
class ValueSourceComparatorSource extends FieldComparatorSource { class ValueSourceComparatorSource extends FieldComparatorSource {

View File

@ -36,7 +36,7 @@ public class TestIndexSearcher extends SolrTestCaseJ4 {
private String getStringVal(SolrQueryRequest sqr, String field, int doc) throws IOException { private String getStringVal(SolrQueryRequest sqr, String field, int doc) throws IOException {
SchemaField sf = sqr.getSchema().getField(field); SchemaField sf = sqr.getSchema().getField(field);
ValueSource vs = sf.getType().getValueSource(sf, null); ValueSource vs = sf.getType().getValueSource(sf, null);
Map context = ValueSource.newContext(); Map context = ValueSource.newContext(sqr.getSearcher());
vs.createWeight(context, sqr.getSearcher()); vs.createWeight(context, sqr.getSearcher());
SolrIndexReader sr = sqr.getSearcher().getReader(); SolrIndexReader sr = sqr.getSearcher().getReader();
int idx = SolrIndexReader.readerIndex(doc, sr.getLeafOffsets()); int idx = SolrIndexReader.readerIndex(doc, sr.getLeafOffsets());