@Override public int start() { return spans.start(); }
@Override public int start() { return requiredSpans.start(); }
@Override public int start() { return parentSpans.start(); }
@Override public int start() { return includeSpans.start(); }
@Override public int start() { return top().start(); }
/** * Returns the slop between the required and optional clauses. */ private int getOptionalSlop() { int totalLength = requiredSpans.end() - requiredSpans.start(); totalLength += optionalSpans.end() - optionalSpans.start(); Spans min = optionalSpans.start() < requiredSpans.start() ? optionalSpans : requiredSpans; Spans max = optionalSpans.end() < requiredSpans.end() ? requiredSpans : optionalSpans; return (max.end() - min.start()) - totalLength; }
@Override protected int getSlop() { // retrieve the min Spans min = queue.top(); return (max.end() - min.start()) - totalLength; }
/** * If an optional clause matches, compute the score of the required and optional clause. We need to recompute the * score of the required clause as the sloppy weight might have changed due to the optional match. */ private float getReqOptScore() throws IOException { int totalLength = 0; float score = 0.0f; for (Spans spans : originalRequiredSpans) { totalLength += spans.end() - spans.start(); score += spans.scoreInNode(); } totalLength += optionalSpans.end() - optionalSpans.start(); score += optionalSpans.scoreInNode(); Spans min = optionalSpans.start() < requiredSpans.start() ? optionalSpans : requiredSpans; Spans max = optionalSpans.end() < requiredSpans.end() ? requiredSpans : optionalSpans; int slop = (max.end() - min.start()) - totalLength; return score * this.sloppyWeight(slop); }
/** * Advances includeSpans to the next non excluded position, if any. {@link #includeSpans} must have been advanced * once to a new position using {@link #nextPosition()}. * * @return true iff the current candidate document and node has a non excluded position. */ private boolean toNonExcludedPosition() throws IOException { boolean moreInclude = true; while (moreInclude) { // moving exclude position to find if there is an overlap while (moreExclude && (excludeSpans.start() == -1 || excludeSpans.end() <= includeSpans.start() - pre)) { moreExclude = excludeSpans.nextPosition(); } // excluded if (moreExclude && excludeSpans.start() < includeSpans.end() + post) { // try another include position moreInclude = includeSpans.nextPosition(); } else { return moreInclude; } } return moreInclude; }
/** * Order the subSpans within the same document and same node by advancing all later spans * after the previous one. */ private boolean stretchToOrder() throws IOException { for (int i = 1; i < subSpans.length; i++) { while (!isSpansOrdered(subSpans[i-1].start(), subSpans[i-1].end(), subSpans[i].start(), subSpans[i].end())) { if (!subSpans[i].nextPosition()) { return false; } } } return true; }
@Override protected final boolean lessThan(Spans spans1, Spans spans2) { if (spans1.doc() == spans2.doc()) { int comparison = NodeUtils.compare(spans1.node(), spans2.node()); if (comparison == 0) { if (spans1.start() == spans2.start()) { return spans1.end() < spans2.end(); } else { return spans1.start() < spans2.start(); } } else { return comparison < 0; } } else { return spans1.doc() < spans2.doc(); } }
/** * Advance the min to its next position, update the total length and the max. */ private boolean advanceMinToNextPosition() throws IOException { // retrieve the min Spans min = queue.top(); // cache length before advancing to the next position int oldLength = min.end() - min.start(); // we advance the min to its next position if (!min.nextPosition()) { return false; } // update total length this.updateTotalLength(oldLength, min.end() - min.start()); // update max reference this.updateMax(min); // update queue queue.updateTop(); return true; }
/** * Initialise the spans by advancing them to their first position, compute the initial total length, and find the max. */ private boolean initialiseSpansPosition() throws IOException { // reset totalLength to 0 totalLength = 0; // reset max max = null; // Initialise the spans, compute the initial total length, and find the max for (Spans spans : subSpans) { if (!spans.nextPosition()) { return false; } // increment total length totalLength += spans.end() - spans.start(); // update max reference this.updateMax(spans); } // rebuild the queue this.rebuildQueue(); return true; }
/** * Move all the least spans in the queue that are positioned on the same document, node and position to their * next position and adjust the heap. * * @return If the least spans has no more positions, returns false. */ public final boolean nextPositionAndAdjust() throws IOException { // Count number of spans, starting from the top, having the same document, node and position. // Add 1 to count the top. int count = this.countPositionEqualToTop(1) + 1; // Move the spans to the next position for (int i = 0; i < count; i++) { this.top().nextPosition(); this.updateTop(); } // if the top's position is the sentinel value, it means that the positions are exhausted return (this.top().start() == PositionsIterator.NO_MORE_POS) ? false : true; }
@Override public boolean nextPosition() throws IOException { if (firstTime) { if (!this.initialiseSpansPosition()) { matchStart = matchEnd = PositionsIterator.NO_MORE_POS; return false; } firstTime = false; } else { if (!this.advanceMinToNextPosition()) { matchStart = matchEnd = PositionsIterator.NO_MORE_POS; return false; } } boolean isMatching; do { // while it is not matching, advance the min to the next position, and try again if (!(isMatching = isMatching())) { if (!this.advanceMinToNextPosition()) { matchStart = matchEnd = PositionsIterator.NO_MORE_POS; return false; } } } while (!isMatching); matchStart = queue.top().start(); matchEnd = max.end(); return isMatching; }
while (optionalSpans.nextPosition() && optionalSpans.start() <= (requiredSpans.end() + allowedOptionalSlop)) {