Class TwoPhaseIterator

java.lang.Object
org.apache.lucene.search.TwoPhaseIterator
Direct Known Subclasses:
DocValuesRangeIterator

public abstract class TwoPhaseIterator extends Object
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.
WARNING: This API is experimental and might change in incompatible ways in the next release.
  • Field Details

  • Constructor Details

    • TwoPhaseIterator

      protected TwoPhaseIterator(DocIdSetIterator approximation)
      Takes the approximation to be returned by approximation. Not null.
  • Method Details

    • asDocIdSetIterator

      public static DocIdSetIterator asDocIdSetIterator(TwoPhaseIterator twoPhaseIterator)
      Return a DocIdSetIterator view of the provided TwoPhaseIterator.
    • unwrap

      public static TwoPhaseIterator unwrap(DocIdSetIterator iterator)
      If the given DocIdSetIterator has been created with asDocIdSetIterator(org.apache.lucene.search.TwoPhaseIterator), then this will return the wrapped TwoPhaseIterator. Otherwise this returns null.
    • approximation

      public DocIdSetIterator approximation()
      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.
    • matches

      public abstract boolean matches() throws IOException
      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.
      Throws:
      IOException
    • matchCost

      public abstract float matchCost()
      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.
    • docIDRunEnd

      public int docIDRunEnd() throws IOException
      Returns the end of the run of consecutive doc IDs that match this TwoPhaseIterator and that contains the current doc ID of the approximation, that is: one plus the last doc ID of the run.

      Note: It is illegal to call this method when the approximation is exhausted or not positioned.

      The default implementation is conservative and returns the current doc ID of the approximation, i.e. it reports no matching run. Unlike a positioned DocIdSetIterator -- whose current doc is by definition a match -- a positioned TwoPhaseIterator has not yet confirmed that the current doc matches, so the default cannot claim it as part of a matching run without a (potentially side-effecting) matches() call. Callers must therefore treat a return value equal to approximation().docID() as "no known matching run" and fall back to per-doc matches() confirmation. Implementations that can cheaply prove that a run of docs matches -- e.g. a doc-values skipper reporting a fully-matching block -- should override this to return the real run end.

      Throws:
      IOException
    • intoBitSet

      public void intoBitSet(int upTo, FixedBitSet bitSet, int offset) throws IOException
      Load the doc IDs that both belong to the approximation() and match, and are in [approximation().docID(), upTo), into bitSet, the document whose ID is i being stored at bit i - offset. Upon return the approximation() is positioned on the first doc that is >= upTo, mirroring DocIdSetIterator.intoBitSet(int, org.apache.lucene.util.FixedBitSet, int).

      The default implementation walks the approximation() and confirms each doc with matches() — i.e. it is functionally identical to the leap-frog evaluation, just writing into a bit set. Implementations that can confirm matches in bulk — for instance a vectorized scan over a columnar block — should override it; the bit set window is then collected in one shot rather than one doc at a time.

      Throws:
      IOException
    • applyMask

      public void applyMask(int upTo, FixedBitSet bitSet, int offset) throws IOException
      Confirms matches() only for the doc IDs whose bit is set in bitSet (the document whose ID is i being stored at bit i - offset), clearing bits for docs that turn out not to match. Upon return approximation() is positioned on the first doc that is >= upTo, mirroring intoBitSet(int, org.apache.lucene.util.FixedBitSet, int).

      Prefer this over intoBitSet(int, org.apache.lucene.util.FixedBitSet, int) followed by a separate intersection when bitSet already holds a candidate set narrowed down by other clauses of a conjunction: it avoids confirming matches for docs that are already known not to be candidates.

      The default implementation walks the set bits of bitSet one at a time, advancing approximation() to each and calling matches(). Implementations that can classify a whole span of a sparse candidate set in bulk -- for instance a block-based skip index that can tell that an entire span is fully matching or fully non-matching without visiting doc values -- should override this.

      Throws:
      IOException