/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.lucene.search;


import java.io.IOException;
import java.util.Objects;

Returned by Scorer.twoPhaseIterator() to expose an approximation of a DocIdSetIterator. When the approximation()'s DocIdSetIterator.nextDoc() or DocIdSetIterator.advance(int) return, matches() needs to be checked in order to know whether the returned doc ID actually matches.
@lucene.experimental
/** * Returned by {@link Scorer#twoPhaseIterator()} * to expose an approximation of a {@link DocIdSetIterator}. * When the {@link #approximation()}'s * {@link DocIdSetIterator#nextDoc()} or {@link DocIdSetIterator#advance(int)} * return, {@link #matches()} needs to be checked in order to know whether the * returned doc ID actually matches. * @lucene.experimental */
public abstract class TwoPhaseIterator { protected final DocIdSetIterator approximation;
Takes the approximation to be returned by approximation. Not null.
/** Takes the approximation to be returned by {@link #approximation}. Not null. */
protected TwoPhaseIterator(DocIdSetIterator approximation) { this.approximation = Objects.requireNonNull(approximation); }
Return a DocIdSetIterator view of the provided TwoPhaseIterator.
/** Return a {@link DocIdSetIterator} view of the provided * {@link TwoPhaseIterator}. */
public static DocIdSetIterator asDocIdSetIterator(TwoPhaseIterator twoPhaseIterator) { return new TwoPhaseIteratorAsDocIdSetIterator(twoPhaseIterator); }
If the given DocIdSetIterator has been created with asDocIdSetIterator, then this will return the wrapped TwoPhaseIterator. Otherwise this returns null.
/** * If the given {@link DocIdSetIterator} has been created with * {@link #asDocIdSetIterator}, then this will return the wrapped * {@link TwoPhaseIterator}. Otherwise this returns {@code null}. */
public static TwoPhaseIterator unwrap(DocIdSetIterator iterator) { if (iterator instanceof TwoPhaseIteratorAsDocIdSetIterator) { return ((TwoPhaseIteratorAsDocIdSetIterator) iterator).twoPhaseIterator; } else { return null; } } private static class TwoPhaseIteratorAsDocIdSetIterator extends DocIdSetIterator { final TwoPhaseIterator twoPhaseIterator; final DocIdSetIterator approximation; TwoPhaseIteratorAsDocIdSetIterator(TwoPhaseIterator twoPhaseIterator) { this.twoPhaseIterator = twoPhaseIterator; this.approximation = twoPhaseIterator.approximation; } @Override public int docID() { return approximation.docID(); } @Override public int nextDoc() throws IOException { return doNext(approximation.nextDoc()); } @Override public int advance(int target) throws IOException { return doNext(approximation.advance(target)); } private int doNext(int doc) throws IOException { for (;; doc = approximation.nextDoc()) { if (doc == NO_MORE_DOCS) { return NO_MORE_DOCS; } else if (twoPhaseIterator.matches()) { return doc; } } } @Override public long cost() { return approximation.cost(); } }
Return an approximation. The returned DocIdSetIterator is a superset of the matching documents, and each match needs to be confirmed with matches() in order to know whether it matches or not.
/** Return an approximation. The returned {@link DocIdSetIterator} is a * superset of the matching documents, and each match needs to be confirmed * with {@link #matches()} in order to know whether it matches or not. */
public DocIdSetIterator approximation() { return approximation; }
Return whether the current doc ID that approximation() is on matches. This method should only be called when the iterator is positioned -- ie. not when DocIdSetIterator.docID() is -1 or DocIdSetIterator.NO_MORE_DOCS -- and at most once.
/** Return whether the current doc ID that {@link #approximation()} is on matches. This * method should only be called when the iterator is positioned -- ie. not * when {@link DocIdSetIterator#docID()} is {@code -1} or * {@link DocIdSetIterator#NO_MORE_DOCS} -- and at most once. */
public abstract boolean matches() throws IOException;
An estimate of the expected cost to determine that a single document matches(). This can be called before iterating the documents of approximation(). Returns an expected cost in number of simple operations like addition, multiplication, comparing two numbers and indexing an array. The returned value must be positive.
/** An estimate of the expected cost to determine that a single document {@link #matches()}. * This can be called before iterating the documents of {@link #approximation()}. * Returns an expected cost in number of simple operations like addition, multiplication, * comparing two numbers and indexing an array. * The returned value must be positive. */
public abstract float matchCost(); }