MtasSpanIntersectingSpans.java

  1. package mtas.search.spans;

  2. import java.io.IOException;

  3. import org.apache.lucene.search.TwoPhaseIterator;
  4. import org.apache.lucene.search.spans.SpanCollector;
  5. import mtas.search.spans.MtasSpanIntersectingQuery.MtasSpanIntersectingQuerySpans;
  6. import mtas.search.spans.util.MtasSpans;

  7. /**
  8.  * The Class MtasSpanIntersectingSpans.
  9.  */
  10. public class MtasSpanIntersectingSpans extends MtasSpans {

  11.   /** The query. */
  12.   private MtasSpanIntersectingQuery query;

  13.   /** The spans 1. */
  14.   private MtasSpanIntersectingQuerySpans spans1;

  15.   /** The spans 2. */
  16.   private MtasSpanIntersectingQuerySpans spans2;

  17.   /** The called next start position. */
  18.   private boolean calledNextStartPosition;

  19.   /** The no more positions. */
  20.   private boolean noMorePositions;

  21.   /** The last spans 2 start position. */
  22.   private int lastSpans2StartPosition;

  23.   /** The last spans 2 end position. */
  24.   private int lastSpans2EndPosition;

  25.   /** The doc id. */
  26.   private int docId;

  27.   /**
  28.    * Instantiates a new mtas span intersecting spans.
  29.    *
  30.    * @param query the query
  31.    * @param spans1 the spans 1
  32.    * @param spans2 the spans 2
  33.    */
  34.   public MtasSpanIntersectingSpans(MtasSpanIntersectingQuery query,
  35.       MtasSpanIntersectingQuerySpans spans1,
  36.       MtasSpanIntersectingQuerySpans spans2) {
  37.     super();
  38.     docId = -1;
  39.     this.query = query;
  40.     this.spans1 = spans1;
  41.     this.spans2 = spans2;
  42.   }

  43.   /*
  44.    * (non-Javadoc)
  45.    *
  46.    * @see org.apache.lucene.search.spans.Spans#nextStartPosition()
  47.    */
  48.   @Override
  49.   public int nextStartPosition() throws IOException {
  50.     // no document
  51.     if (docId == -1 || docId == NO_MORE_DOCS) {
  52.       throw new IOException("no document");
  53.       // finished
  54.     } else if (noMorePositions) {
  55.       return NO_MORE_POSITIONS;
  56.       // littleSpans already at start match, because of check for matching
  57.       // document
  58.     } else if (!calledNextStartPosition) {
  59.       calledNextStartPosition = true;
  60.       return spans1.spans.startPosition();
  61.       // compute next match
  62.     } else {
  63.       if (goToNextStartPosition()) {
  64.         // match found
  65.         return spans1.spans.startPosition();
  66.       } else {
  67.         // no more matches: document finished
  68.         return NO_MORE_POSITIONS;
  69.       }
  70.     }
  71.   }

  72.   /*
  73.    * (non-Javadoc)
  74.    *
  75.    * @see org.apache.lucene.search.spans.Spans#startPosition()
  76.    */
  77.   @Override
  78.   public int startPosition() {
  79.     return calledNextStartPosition
  80.         ? (noMorePositions ? NO_MORE_POSITIONS : spans1.spans.startPosition())
  81.         : -1;
  82.   }

  83.   /*
  84.    * (non-Javadoc)
  85.    *
  86.    * @see org.apache.lucene.search.spans.Spans#endPosition()
  87.    */
  88.   @Override
  89.   public int endPosition() {
  90.     return calledNextStartPosition
  91.         ? (noMorePositions ? NO_MORE_POSITIONS : spans1.spans.endPosition())
  92.         : -1;
  93.   }

  94.   /*
  95.    * (non-Javadoc)
  96.    *
  97.    * @see org.apache.lucene.search.spans.Spans#width()
  98.    */
  99.   @Override
  100.   public int width() {
  101.     return calledNextStartPosition ? (noMorePositions ? 0
  102.         : spans1.spans.endPosition() - spans1.spans.startPosition()) : 0;
  103.   }

  104.   /*
  105.    * (non-Javadoc)
  106.    *
  107.    * @see
  108.    * org.apache.lucene.search.spans.Spans#collect(org.apache.lucene.search.spans
  109.    * .SpanCollector)
  110.    */
  111.   @Override
  112.   public void collect(SpanCollector collector) throws IOException {
  113.     spans1.spans.collect(collector);
  114.     spans2.spans.collect(collector);
  115.   }

  116.   /*
  117.    * (non-Javadoc)
  118.    *
  119.    * @see org.apache.lucene.search.spans.Spans#positionsCost()
  120.    */
  121.   @Override
  122.   public float positionsCost() {
  123.     return 0;
  124.   }

  125.   /*
  126.    * (non-Javadoc)
  127.    *
  128.    * @see org.apache.lucene.search.DocIdSetIterator#docID()
  129.    */
  130.   @Override
  131.   public int docID() {
  132.     return docId;
  133.   }

  134.   /*
  135.    * (non-Javadoc)
  136.    *
  137.    * @see org.apache.lucene.search.DocIdSetIterator#nextDoc()
  138.    */
  139.   @Override
  140.   public int nextDoc() throws IOException {
  141.     reset();
  142.     while (!goToNextDoc())
  143.       ;
  144.     return docId;
  145.   }

  146.   /*
  147.    * (non-Javadoc)
  148.    *
  149.    * @see org.apache.lucene.search.DocIdSetIterator#advance(int)
  150.    */
  151.   @Override
  152.   public int advance(int target) throws IOException {
  153.     reset();
  154.     if (docId == NO_MORE_DOCS) {
  155.       return docId;
  156.     } else if (target < docId) {
  157.       // should not happen
  158.       docId = NO_MORE_DOCS;
  159.       return docId;
  160.     } else {
  161.       // advance 1
  162.       int spans1DocId = spans1.spans.docID();
  163.       int newTarget = target;
  164.       if (spans1DocId < newTarget) {
  165.         spans1DocId = spans1.spans.advance(newTarget);
  166.         if (spans1DocId == NO_MORE_DOCS) {
  167.           docId = NO_MORE_DOCS;
  168.           return docId;
  169.         }
  170.         newTarget = Math.max(newTarget, spans1DocId);
  171.       }
  172.       int spans2DocId = spans2.spans.docID();
  173.       // advance 2
  174.       if (spans2DocId < newTarget) {
  175.         spans2DocId = spans2.spans.advance(newTarget);
  176.         if (spans2DocId == NO_MORE_DOCS) {
  177.           docId = NO_MORE_DOCS;
  178.           return docId;
  179.         }
  180.       }
  181.       // check equal docId, otherwise next
  182.       if (spans1DocId == spans2DocId) {
  183.         docId = spans1DocId;
  184.         // check match
  185.         if (goToNextStartPosition()) {
  186.           return docId;
  187.         } else {
  188.           return nextDoc();
  189.         }
  190.       } else {
  191.         return nextDoc();
  192.       }
  193.     }
  194.   }

  195.   /**
  196.    * Go to next doc.
  197.    *
  198.    * @return true, if successful
  199.    * @throws IOException Signals that an I/O exception has occurred.
  200.    */
  201.   private boolean goToNextDoc() throws IOException {
  202.     if (docId == NO_MORE_DOCS) {
  203.       return true;
  204.     } else {
  205.       int spans1DocId = spans1.spans.nextDoc();
  206.       int spans2DocId = spans2.spans.docID();
  207.       docId = Math.max(spans1DocId, spans2DocId);
  208.       while (spans1DocId != spans2DocId && docId != NO_MORE_DOCS) {
  209.         if (spans1DocId < spans2DocId) {
  210.           spans1DocId = spans1.spans.advance(spans2DocId);
  211.           docId = spans1DocId;
  212.         } else {
  213.           spans2DocId = spans2.spans.advance(spans1DocId);
  214.           docId = spans2DocId;
  215.         }
  216.       }
  217.       if (docId != NO_MORE_DOCS) {
  218.         if (!goToNextStartPosition()) {
  219.           reset();
  220.           return false;
  221.         }
  222.       }
  223.       return true;
  224.     }
  225.   }

  226.   /**
  227.    * Go to next start position.
  228.    *
  229.    * @return true, if successful
  230.    * @throws IOException Signals that an I/O exception has occurred.
  231.    */
  232.   private boolean goToNextStartPosition() throws IOException {
  233.     int nextSpans1StartPosition;
  234.     int nextSpans1EndPosition;
  235.     int nextSpans2StartPosition;
  236.     int nextSpans2EndPosition;
  237.     while ((nextSpans1StartPosition = spans1.spans
  238.         .nextStartPosition()) != NO_MORE_POSITIONS) {
  239.       nextSpans1EndPosition = spans1.spans.endPosition();
  240.       if (nextSpans1StartPosition <= lastSpans2EndPosition
  241.           && nextSpans1EndPosition >= lastSpans2StartPosition) {
  242.         return true;
  243.       } else {
  244.         while (lastSpans2StartPosition <= nextSpans1EndPosition) {
  245.           nextSpans2StartPosition = spans2.spans.nextStartPosition();
  246.           if (nextSpans2StartPosition == NO_MORE_POSITIONS) {
  247.             noMorePositions = true;
  248.             return false;
  249.           } else {
  250.             nextSpans2EndPosition = spans2.spans.endPosition();
  251.             if (nextSpans2StartPosition > lastSpans2StartPosition
  252.                 || nextSpans2EndPosition > lastSpans2EndPosition) {
  253.               if (nextSpans2EndPosition > lastSpans2EndPosition) {
  254.                 lastSpans2StartPosition = nextSpans2StartPosition;
  255.                 lastSpans2EndPosition = nextSpans2EndPosition;
  256.                 if (nextSpans1StartPosition <= lastSpans2EndPosition
  257.                     && nextSpans1EndPosition >= lastSpans2StartPosition) {
  258.                   return true;
  259.                 }
  260.               }
  261.             }
  262.           }
  263.         }
  264.       }
  265.     }
  266.     noMorePositions = true;
  267.     return false;
  268.   }

  269.   /**
  270.    * Reset.
  271.    */
  272.   private void reset() {
  273.     calledNextStartPosition = false;
  274.     noMorePositions = false;
  275.     lastSpans2StartPosition = -1;
  276.     lastSpans2EndPosition = -1;
  277.   }

  278.   /*
  279.    * (non-Javadoc)
  280.    *
  281.    * @see org.apache.lucene.search.DocIdSetIterator#cost()
  282.    */
  283.   @Override
  284.   public long cost() {
  285.     return 0;
  286.   }

  287.   /*
  288.    * (non-Javadoc)
  289.    *
  290.    * @see mtas.search.spans.util.MtasSpans#asTwoPhaseIterator()
  291.    */
  292.   @Override
  293.   public TwoPhaseIterator asTwoPhaseIterator() {
  294.     if (spans1 == null || spans2 == null || !query.twoPhaseIteratorAllowed()) {
  295.       return null;
  296.     } else {
  297.       // TODO
  298.       return null;
  299.     }
  300.   }

  301. }