Skip to content

Commit 6c56c38

Browse files
authored
Implement ScorerSupplier for ShapeDocValuesQuery (#93883)
Implement ScoreSuppler and move expensive operations in there and only execute them if based on the cost(), IndexOrDocValuesQuery decides not to use this query.
1 parent df4a8f7 commit 6c56c38

File tree

1 file changed

+78
-35
lines changed

1 file changed

+78
-35
lines changed

x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/mapper/ShapeDocValuesQuery.java

Lines changed: 78 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.apache.lucene.search.QueryVisitor;
2020
import org.apache.lucene.search.ScoreMode;
2121
import org.apache.lucene.search.Scorer;
22+
import org.apache.lucene.search.ScorerSupplier;
2223
import org.apache.lucene.search.TwoPhaseIterator;
2324
import org.apache.lucene.search.Weight;
2425
import org.elasticsearch.xpack.spatial.index.fielddata.Component2DVisitor;
@@ -105,41 +106,61 @@ public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float bo
105106
}
106107

107108
private ConstantScoreWeight getStandardWeight(ScoreMode scoreMode, float boost) {
109+
final Component2D component2D = create(geometries);
108110
return new ConstantScoreWeight(this, boost) {
109-
final Component2D component2D = create(geometries);
110111

111112
@Override
112113
public Scorer scorer(LeafReaderContext context) throws IOException {
113-
final BinaryDocValues values = context.reader().getBinaryDocValues(field);
114-
if (values == null) {
114+
final ScorerSupplier scorerSupplier = scorerSupplier(context);
115+
if (scorerSupplier == null) {
115116
return null;
116117
}
117-
final GeometryDocValueReader reader = new GeometryDocValueReader();
118-
final Component2DVisitor visitor = Component2DVisitor.getVisitor(component2D, relation, encoder);
118+
return scorerSupplier.get(Long.MAX_VALUE);
119+
}
119120

120-
final TwoPhaseIterator iterator = new TwoPhaseIterator(values) {
121+
@Override
122+
public ScorerSupplier scorerSupplier(LeafReaderContext context) {
123+
final Weight weight = this;
124+
// implement ScorerSupplier, since we do some expensive stuff to make a scorer
125+
return new ScorerSupplier() {
121126

122127
@Override
123-
public boolean matches() throws IOException {
124-
reader.reset(values.binaryValue());
125-
visitor.reset();
126-
reader.visit(visitor);
127-
return visitor.matches();
128+
public Scorer get(long leadCost) throws IOException {
129+
// binary doc values allocate an array upfront, lets only allocate it if we are going to use it
130+
final BinaryDocValues values = context.reader().getBinaryDocValues(field);
131+
if (values == null) {
132+
return null;
133+
}
134+
final GeometryDocValueReader reader = new GeometryDocValueReader();
135+
final Component2DVisitor visitor = Component2DVisitor.getVisitor(component2D, relation, encoder);
136+
final TwoPhaseIterator iterator = new TwoPhaseIterator(values) {
137+
@Override
138+
public boolean matches() throws IOException {
139+
reader.reset(values.binaryValue());
140+
visitor.reset();
141+
reader.visit(visitor);
142+
return visitor.matches();
143+
}
144+
145+
@Override
146+
public float matchCost() {
147+
return 1000f; // TODO: what should it be?
148+
}
149+
};
150+
return new ConstantScoreScorer(weight, score(), scoreMode, iterator);
128151
}
129152

130153
@Override
131-
public float matchCost() {
132-
return 1000f; // TODO: what should it be?
154+
public long cost() {
155+
return context.reader().maxDoc();
133156
}
134157
};
135-
return new ConstantScoreScorer(this, boost, scoreMode, iterator);
136158
}
137159

138160
@Override
139161
public boolean isCacheable(LeafReaderContext ctx) {
140162
return DocValues.isCacheable(ctx, field);
141163
}
142-
143164
};
144165
}
145166

@@ -152,37 +173,59 @@ private ConstantScoreWeight getContainsWeight(ScoreMode scoreMode, float boost)
152173

153174
@Override
154175
public Scorer scorer(LeafReaderContext context) throws IOException {
155-
final BinaryDocValues values = context.reader().getBinaryDocValues(field);
156-
if (values == null) {
176+
final ScorerSupplier scorerSupplier = scorerSupplier(context);
177+
if (scorerSupplier == null) {
157178
return null;
158179
}
159-
final GeometryDocValueReader reader = new GeometryDocValueReader();
160-
final Component2DVisitor[] visitors = new Component2DVisitor[components2D.size()];
161-
for (int i = 0; i < components2D.size(); i++) {
162-
visitors[i] = Component2DVisitor.getVisitor(components2D.get(i), relation, encoder);
163-
}
180+
return scorerSupplier.get(Long.MAX_VALUE);
181+
}
164182

165-
final TwoPhaseIterator iterator = new TwoPhaseIterator(values) {
183+
@Override
184+
public ScorerSupplier scorerSupplier(LeafReaderContext context) {
185+
final Weight weight = this;
186+
// implement ScorerSupplier, since we do some expensive stuff to make a scorer
187+
return new ScorerSupplier() {
166188

167189
@Override
168-
public boolean matches() throws IOException {
169-
reader.reset(values.binaryValue());
170-
for (Component2DVisitor visitor : visitors) {
171-
visitor.reset();
172-
reader.visit(visitor);
173-
if (visitor.matches() == false) {
174-
return false;
175-
}
190+
public Scorer get(long leadCost) throws IOException {
191+
// binary doc values allocate an array upfront, lets only allocate it if we are going to use it
192+
final BinaryDocValues values = context.reader().getBinaryDocValues(field);
193+
if (values == null) {
194+
return null;
195+
}
196+
final Component2DVisitor[] visitors = new Component2DVisitor[components2D.size()];
197+
for (int i = 0; i < components2D.size(); i++) {
198+
visitors[i] = Component2DVisitor.getVisitor(components2D.get(i), relation, encoder);
176199
}
177-
return true;
200+
final GeometryDocValueReader reader = new GeometryDocValueReader();
201+
final TwoPhaseIterator iterator = new TwoPhaseIterator(values) {
202+
203+
@Override
204+
public boolean matches() throws IOException {
205+
reader.reset(values.binaryValue());
206+
for (Component2DVisitor visitor : visitors) {
207+
visitor.reset();
208+
reader.visit(visitor);
209+
if (visitor.matches() == false) {
210+
return false;
211+
}
212+
}
213+
return true;
214+
}
215+
216+
@Override
217+
public float matchCost() {
218+
return 1000f; // TODO: what should it be?
219+
}
220+
};
221+
return new ConstantScoreScorer(weight, score(), scoreMode, iterator);
178222
}
179223

180224
@Override
181-
public float matchCost() {
182-
return 1000f; // TODO: what should it be?
225+
public long cost() {
226+
return context.reader().maxDoc();
183227
}
184228
};
185-
return new ConstantScoreScorer(this, boost, scoreMode, iterator);
186229
}
187230

188231
@Override

0 commit comments

Comments
 (0)