3131import org .apache .lucene .search .IndexSearcher ;
3232import org .apache .lucene .search .Query ;
3333import org .apache .lucene .search .Scorer ;
34+ import org .apache .lucene .search .TwoPhaseIterator ;
3435import org .apache .lucene .search .Weight ;
3536import org .apache .lucene .util .BitSetIterator ;
3637import org .apache .lucene .util .Bits ;
3738import org .apache .lucene .util .BytesRef ;
3839import org .apache .lucene .util .FixedBitSet ;
40+ import org .elasticsearch .Version ;
3941import org .elasticsearch .cluster .metadata .IndexMetaData ;
4042import org .elasticsearch .cluster .routing .OperationRouting ;
4143import org .elasticsearch .index .mapper .IdFieldMapper ;
@@ -56,6 +58,10 @@ final class ShardSplittingQuery extends Query {
5658 private final int shardId ;
5759
5860 ShardSplittingQuery (IndexMetaData indexMetaData , int shardId ) {
61+ if (indexMetaData .getCreationVersion ().before (Version .V_6_0_0_rc2 )) {
62+ throw new IllegalArgumentException ("Splitting query can only be executed on an index created with version "
63+ + Version .V_6_0_0_rc2 + " or higher" );
64+ }
5965 this .indexMetaData = indexMetaData ;
6066 this .shardId = shardId ;
6167 }
@@ -87,7 +93,7 @@ public Scorer scorer(LeafReaderContext context) throws IOException {
8793 Bits liveDocs = leafReader .getLiveDocs ();
8894 Visitor visitor = new Visitor ();
8995 return new ConstantScoreScorer (this , score (),
90- new RoutingPartitionedDocIdSetIterator (leafReader , liveDocs , visitor ));
96+ new RoutingPartitionedDocIdSetIterator (leafReader , visitor ));
9197 } else {
9298 // in the _routing case we first go and find all docs that have a routing value and mark the ones we have to delete
9399 findSplitDocs (RoutingFieldMapper .NAME , ref -> {
@@ -111,6 +117,8 @@ public Scorer scorer(LeafReaderContext context) throws IOException {
111117 }
112118 return new ConstantScoreScorer (this , score (), new BitSetIterator (bitSet , bitSet .length ()));
113119 }
120+
121+
114122 };
115123 }
116124
@@ -121,12 +129,12 @@ public String toString(String field) {
121129
122130 @ Override
123131 public boolean equals (Object o ) {
124- return sameClassAs ( o );
132+ throw new UnsupportedOperationException ( "only use this query for deleting documents" );
125133 }
126134
127135 @ Override
128136 public int hashCode () {
129- return classHash ( );
137+ throw new UnsupportedOperationException ( "only use this query for deleting documents" );
130138 }
131139
132140 private static void findSplitDocs (String idField , Predicate <BytesRef > includeInShard ,
@@ -184,64 +192,44 @@ public void stringField(FieldInfo fieldInfo, byte[] value) throws IOException {
184192
185193 @ Override
186194 public Status needsField (FieldInfo fieldInfo ) throws IOException {
195+ // we don't support 5.x so no need for the uid field
187196 switch (fieldInfo .name ) {
188197 case IdFieldMapper .NAME :
189198 case RoutingFieldMapper .NAME :
190199 leftToVisit --;
191200 return Status .YES ;
192201 default :
193202 return leftToVisit == 0 ? Status .STOP : Status .NO ;
194-
195203 }
196204 }
197205 }
198206
199207 /**
200- * This DISI visits every live doc and selects all docs that don't belong into this
201- * shard based on their id and rounting value. This is only used in a routing partitioned index.
208+ * This two phase iterator visits every live doc and selects all docs that don't belong into this
209+ * shard based on their id and routing value. This is only used in a routing partitioned index.
202210 */
203- private final class RoutingPartitionedDocIdSetIterator extends DocIdSetIterator {
211+ private final class RoutingPartitionedDocIdSetIterator extends TwoPhaseIterator {
204212 private final LeafReader leafReader ;
205- private final Bits liveDocs ;
206213 private final Visitor visitor ;
207- private int doc ;
208214
209- RoutingPartitionedDocIdSetIterator (LeafReader leafReader , Bits liveDocs , Visitor visitor ) {
215+ RoutingPartitionedDocIdSetIterator (LeafReader leafReader , Visitor visitor ) {
216+ super (DocIdSetIterator .all (leafReader .maxDoc ())); // we iterate all live-docs
210217 this .leafReader = leafReader ;
211- this .liveDocs = liveDocs ;
212218 this .visitor = visitor ;
213- doc = -1 ;
214- }
215-
216- @ Override
217- public int docID () {
218- return doc ;
219- }
220-
221- @ Override
222- public int nextDoc () throws IOException {
223- while (++doc < leafReader .maxDoc ()) {
224- if (liveDocs == null || liveDocs .get (doc )) {
225- visitor .reset ();
226- leafReader .document (doc , visitor );
227- int targetShardId = OperationRouting .generateShardId (indexMetaData , visitor .id , visitor .routing );
228- if (targetShardId != shardId ) { // move to next doc if we can keep it
229- return doc ;
230- }
231- }
232- }
233- return doc = DocIdSetIterator .NO_MORE_DOCS ;
234219 }
235220
236221 @ Override
237- public int advance (int target ) throws IOException {
238- while (nextDoc () < target ) {}
239- return doc ;
222+ public boolean matches () throws IOException {
223+ int doc = approximation .docID ();
224+ visitor .reset ();
225+ leafReader .document (doc , visitor );
226+ int targetShardId = OperationRouting .generateShardId (indexMetaData , visitor .id , visitor .routing );
227+ return targetShardId != shardId ;
240228 }
241229
242230 @ Override
243- public long cost () {
244- return leafReader . maxDoc ();
231+ public float matchCost () {
232+ return 42 ; // that's obvious, right?
245233 }
246234 }
247235}
0 commit comments